使用QPainter绘制散点图,用到极致

这段代码展示了如何使用QPainter在Qt环境中绘制散点图,强调了自定义和速度的优势。它首先创建图像并填充背景,然后定义坐标轴和刻度,最后根据数据点绘制图形,包括不同条件下的点颜色。同时,代码还涉及到了与OpenCV数据的集成,用于显示不同亮度阈值的数据分布。
摘要由CSDN通过智能技术生成

使用QPainter绘制散点图,好处就是随意diy,不受限制,而且速度快。

//画图框架
void Scatter2DDrawFrame()
{
    int winWidth = m_pAnalysis1DScatterLbl->width();
    int winHeight = m_pAnalysis1DScatterLbl->height();

    m_scatter2DImage = QImage(winWidth, winHeight, QImage::Format_RGB32);
    QColor backColor = qRgb(255, 255, 255);
    m_scatter2DImage.fill(backColor);
    m_scatter2DPainter = new QPainter(&m_scatter2DImage);
    m_scatter2DPainter->setRenderHint(QPainter::Antialiasing, true);

    int pointx = 50, pointy = winHeight-50;
    int width = winWidth - pointx - 50;  // 宽度 = 画布宽度 - 坐标起点x - 右端间隙
    int height = winHeight - 2 * 50;      // 高度 = 画布高度 - 上下端的间隙高度

    QPen penDegree;
    penDegree.setColor(QColor(65,105,225));
    penDegree.setWidth(2);
    m_scatter2DPainter->setPen(penDegree);
    // 绘制X、Y1、Y2轴
    QPointF xStartPoint(pointx, pointy);
    QPointF xEndPoint(width + pointx, pointy);
    m_scatter2DPainter->drawLine(xStartPoint, xEndPoint); // 坐标轴x宽度为width


    QPointF y1StartPoint(pointx, pointy - height);
    QPointF y1EndPoint(pointx, pointy);
    m_scatter2DPainter->drawLine(y1StartPoint, y1EndPoint); // 坐标轴y1高度为height


    //y-degree
    m_scatter2DPainter->drawText(pointx + 3, pointy +12, QString::number(0));
    for(int i = 0; i < 5; i++)
    {
      m_scatter2DPainter->drawText(pointx+(i+0.9) * width / 5, pointy+22, QString::number(255/5*(i+1)));
      xStartPoint = QPointF(pointx+(i+1.0)*width / 5, pointy);
      xEndPoint = QPointF(pointx+(i+1.0)*width / 5, pointy+8);
      m_scatter2DPainter->drawLine(xStartPoint, xEndPoint);
    }

    //x-degree
    m_scatter2DPainter->drawText(pointx - 25, pointy - 3, QString::number(0));
    for(int i = 0; i < 5; i++)
    {
      m_scatter2DPainter->drawText(pointx-30, pointy-(i+0.95)*height/5, QString::number(255/5*(i+1)));
      xStartPoint.setX(pointx-8);
      xStartPoint.setY(pointy - (i+1.0) * height/5 );
      xEndPoint.setX(pointx);
      xEndPoint.setY(pointy - (i+1.0) * height/5);
      m_scatter2DPainter->drawLine(xStartPoint, xEndPoint);
    }

}

添加数据部分:

  //添加数据
  
  void CNewExperiment::Scatter2DAddData()
{
    int winWidth = m_pAnalysis2DScatterLbl->width();
    int winHeight = m_pAnalysis2DScatterLbl->height();
    m_scatter2DPainter->fillRect(0, 0, winWidth, winHeight, Qt::white);

    int pointx = 50, pointy = winHeight-50;
    int width = winWidth - pointx - 50;  // 宽度 = 画布宽度 - 坐标起点x - 右端间隙
    int height = winHeight - 2 * 50;      // 高度 = 画布高度 - 上下端的间隙高度
    double ky = 0;
    double kx = 0;

    uint dropletsCount = 0;
    uint selectCount = 0;
    QStringList wellList;

    for(WellIdItem item : m_analysisWellIdList)
    {
        if(item.check->isChecked())
        {
            wellList.append(item.label->text());
            selectCount++;
        }
    }
    QPen penDegree;
    penDegree.setColor(QColor(65,105,225));
    penDegree.setWidth(2);
    m_scatter2DPainter->setPen(penDegree);

    // 绘制X、Y轴
    QPointF xStartPoint(pointx, pointy);
    QPointF xEndPoint(width + pointx, pointy);
    m_scatter2DPainter->drawLine(xStartPoint, xEndPoint); // 坐标轴x宽度为width


    QPointF y1StartPoint(pointx, pointy - height);
    QPointF y1EndPoint(pointx, pointy);
    m_scatter2DPainter->drawLine(y1StartPoint, y1EndPoint); // 坐标轴y高度为height


    //x-degree
    m_scatter2DPainter->drawText(pointx + 3, pointy +12, QString::number(0));
    for(int i = 0; i < 5; i++)
    {
        m_scatter2DPainter->drawText(pointx+(i+0.9) * width / 5, pointy+22, QString::number(255/5*(i+1)));
        xStartPoint = QPointF(pointx+(i+1.0)*width / 5, pointy);
        xEndPoint = QPointF(pointx+(i+1.0)*width / 5, pointy+8);
        m_scatter2DPainter->drawLine(xStartPoint, xEndPoint);
    }

    //y-degree
    m_scatter2DPainter->drawText(pointx - 25, pointy - 3, QString::number(0));
    for(int i = 0; i < 5; i++)
    {
        m_scatter2DPainter->drawText(pointx-30, pointy-(i+0.95)*height/5, QString::number(255/5*(i+1)));
        xStartPoint.setX(pointx-8);
        xStartPoint.setY(pointy - (i+1.0) * height/5 );
        xEndPoint.setX(pointx);
        xEndPoint.setY(pointy - (i+1.0) * height/5);
        m_scatter2DPainter->drawLine(xStartPoint, xEndPoint);
    }

    if(selectCount == 0 || m_currfluoList.size() <= 1)
    {
        return;
    }


    QStringList filelist;

    QPen penOne, penTwo, penThree, penFour, thresholdH, thresholdV;
    penOne.setColor(QColor(227,23,13));
    penOne.setWidth(2);

    penTwo.setColor(QColor(0,255,255));
    penTwo.setWidth(2);

    penThree.setColor(QColor(65,105,225));
    penThree.setWidth(2);

    penFour.setColor(QColor(128,138,135));
    penFour.setWidth(2);

    thresholdH.setColor(QColor(227,23,13));
    thresholdH.setWidth(2);
    thresholdH.setStyle(Qt::SolidLine);

    thresholdV.setColor(QColor(65,105,225));
    thresholdV.setWidth(2);
    thresholdV.setStyle(Qt::SolidLine);


    int idx = 0;
    for(QString well : wellList)
    {
        for(QString x : m_currXYValList)
        {
            for(auto it = m_selectedList.begin(); it != m_selectedList.end(); it++)
            {
                if(it.key() == well && it.value().indexOf(x) >= 0)
                {
                    if(filelist.indexOf(it.value()) < 0)
                        filelist.append(it.value());
                    if(++idx >= 2)
                    {
                        idx = 0;
                        break;
                    }
                }
            }
        }
    }

    kx = (double)width / Y_MAX_VALUE;  // y方向的比例系数
    ky = (double)height / Y_MAX_VALUE;  // y方向的比例系数

    if(filelist.size() >= 2 && filelist.size() % 2 == 0)
    {
        for(int index = 0; index < filelist.size(); index+=2)
        {
            for(int i = 0; i < m_pOpencvProcess->m_allDropletsInfo[filelist[index]].size(); i++)
            {
                if(m_pOpencvProcess->m_allDropletsInfo[filelist[index]][i].luminance > m_iDefaultThreshVal && m_pOpencvProcess->m_allDropletsInfo[filelist[index+1]][i].luminance < m_iDefaultThreshVal)
                {
                    m_scatter2DPainter->setPen(penFour);
                    m_scatter2DPainter->drawPoint(m_pOpencvProcess->m_allDropletsInfo[filelist[index]][i].luminance*kx+pointx,
                            pointy - m_pOpencvProcess->m_allDropletsInfo[filelist[index+1]][i].luminance*ky);

                }
                else if(m_pOpencvProcess->m_allDropletsInfo[filelist[index]][i].luminance < m_iDefaultThreshVal && m_pOpencvProcess->m_allDropletsInfo[filelist[index+1]][i].luminance < m_iDefaultThreshVal)
                {
                    m_scatter2DPainter->setPen(penThree);
                    m_scatter2DPainter->drawPoint(m_pOpencvProcess->m_allDropletsInfo[filelist[index]][i].luminance*kx+pointx,
                            pointy - m_pOpencvProcess->m_allDropletsInfo[filelist[index+1]][i].luminance*ky);
                }
                else if(m_pOpencvProcess->m_allDropletsInfo[filelist[index]][i].luminance > m_iDefaultThreshVal && m_pOpencvProcess->m_allDropletsInfo[filelist[index+1]][i].luminance > m_iDefaultThreshVal)
                {
                    m_scatter2DPainter->setPen(penTwo);
                    m_scatter2DPainter->drawPoint(m_pOpencvProcess->m_allDropletsInfo[filelist[index]][i].luminance*kx+pointx,
                            pointy - m_pOpencvProcess->m_allDropletsInfo[filelist[index+1]][i].luminance*ky);
                }
                else if(m_pOpencvProcess->m_allDropletsInfo[filelist[index]][i].luminance < m_iDefaultThreshVal && m_pOpencvProcess->m_allDropletsInfo[filelist[index+1]][i].luminance > m_iDefaultThreshVal)
                {
                    m_scatter2DPainter->setPen(penOne);
                    m_scatter2DPainter->drawPoint(m_pOpencvProcess->m_allDropletsInfo[filelist[index]][i].luminance*kx+pointx,
                            pointy - m_pOpencvProcess->m_allDropletsInfo[filelist[index+1]][i].luminance*ky);

                }
            }
        }
    }

    if(filelist.size() >= 2)
    {
        m_scatter2DPainter->setPen(thresholdH);
        QPointF xStartPoint(pointx, pointy - m_iDefaultThreshVal*ky);
        QPointF xEndPoint(pointx + width, pointy - m_iDefaultThreshVal*ky);
        m_scatter2DPainter->drawLine(xStartPoint, xEndPoint);

        m_scatter2DPainter->setPen(thresholdV);
        xStartPoint.setX(pointx + m_iDefaultThreshVal*kx);
        xStartPoint.setY(pointy);
        xEndPoint.setX(pointx + m_iDefaultThreshVal*kx);
        xEndPoint.setY(pointy - height);
        m_scatter2DPainter->drawLine(xStartPoint, xEndPoint);
    }

    m_scatter2DPainter->setPen(penDegree);
    m_scatter2DPainter->drawText(width / 2, pointy + 32, m_currXYValList[0]);
    m_scatter2DPainter->translate(pointx-40, pointy - height / 2+10);
    m_scatter2DPainter->rotate(-90);
    m_scatter2DPainter->drawText(0, 0, m_currXYValList[1]);
    m_scatter2DPainter->resetMatrix();
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值