利用QPainter绘制散点图
【1】实例代码
(1)代码目录结构(备注:QtCreator默认步骤新建工程)
(2)工程pro文件
- QT += core gui
- greaterThan(QT_MAJOR_VERSION, ): QT += widgets
- TARGET = painter
- TEMPLATE = app
- SOURCES += main.cpp\
- mainwindow.cpp
- HEADERS += mainwindow.h
- FORMS += mainwindow.ui
(3)头文件
- #ifndef MAINWINDOW_H
- #define MAINWINDOW_H
- #include <QtGui>
- #include <QPaintEvent>
- #include <QMainWindow>
- #include <ctime>
- #include <cstdlib>
- namespace Ui
- {
- class MainWindow;
- }
- class MainWindow : public QMainWindow
- {
- Q_OBJECT
- public:
- explicit MainWindow(QWidget *parent = );
- ~MainWindow();
- void Paint();
- public slots:
- void onRefresh();
- protected:
- void paintEvent(QPaintEvent *);
- private:
- Ui::MainWindow *ui;
- QImage m_image;
- QPainter *m_painter;
- };
- #endif // MAINWINDOW_H
(4)实现文件
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- #define POINTSNUM 10
- #define LowerFactor 0.8
- #define UpperFactor 1.2
- typedef struct Data
- {
- double scaleRange;
- double maxScale;
- double minScale;
- QVector<double> vecData;
- Data() : scaleRange(0.0), maxScale(0.0), minScale(0.0)
- {}
- void init()
- {
- for (int i = ; i < POINTSNUM; ++i)
- {
- if (i % )
- vecData.append(rand() % - );
- else
- vecData.append(rand() % + );
- }
- double maxElement = *(std::max_element(vecData.begin(), vecData.end()));
- double minElement = *(std::min_element(vecData.begin(), vecData.end()));
- if (maxElement < )
- {
- maxScale = maxElement * LowerFactor;
- minScale = minElement * UpperFactor;
- }
- else if ( == maxElement)
- {
- maxScale = ;
- minScale = minElement * UpperFactor;
- }
- else if (maxElement > && minElement < )
- {
- maxScale = maxElement * UpperFactor;
- minScale = minElement * UpperFactor;
- }
- else if (minElement > )
- {
- maxScale = maxElement * UpperFactor;
- minScale = minElement * LowerFactor;
- }
- scaleRange = maxScale - minScale;
- }
- void print()
- {
- for (int i = ; i < POINTSNUM; ++i)
- {
- qDebug () << i << "::" << vecData[i] << " ";
- }
- qDebug() << endl;
- }
- }DataInfo;
- MainWindow::MainWindow(QWidget *parent)
- : QMainWindow(parent),
- ui(new Ui::MainWindow)
- {
- ui->setupUi(this);
- ui->mainToolBar->setVisible(true);
- QAction *pAction = new QAction("refresh", this);
- ui->mainToolBar->addAction(pAction);
- connect(pAction, &QAction::triggered, this, &MainWindow::onRefresh);
- resize(, ); // 窗体大小 宽度1000 高度730
- m_image = QImage(, , QImage::Format_RGB32); // 画布的初始化大小设为,使用32位颜色
- QColor backColor = qRgb(, , ); // 画布初始化背景色使用白色
- m_image.fill(backColor); // 对画布进行填充
- m_painter = new QPainter(&m_image);
- m_painter->setRenderHint(QPainter::Antialiasing, true); // 设置反锯齿模式
- Paint();
- }
- void MainWindow::onRefresh()
- {
- m_painter->fillRect(, , - , - , Qt::white);
- Paint();
- update();
- }
- void MainWindow::Paint()
- {
- // 确定坐标轴起点坐标
- int pointx = , pointy = ;
- // 确定坐标轴宽度和高度,上文已定义画布大小,宽高依此而定。
- int width = - pointx - ; // 宽度 = 画布宽度 - 坐标起点x - 右端间隙
- int height = - * ; // 高度 = 画布高度 - 上下端的间隙高度
- // 绘制视图区域
- // 即外围的矩形(由左上角与右下角的两个点确定一个矩形)
- m_painter->drawRect(, , - , - );
- // 绘制X、Y1、Y2轴
- QPointF xStartPoint(pointx, pointy);
- QPointF xEndPoint(width + pointx, pointy);
- m_painter->drawLine(xStartPoint, xEndPoint); // 坐标轴x宽度为width
- QPointF y1StartPoint(pointx, pointy - height);
- QPointF y1EndPoint(pointx, pointy);
- m_painter->drawLine(y1StartPoint, y1EndPoint); // 坐标轴y1高度为height
- QPointF y2StartPoint(pointx + width, pointy - height);
- QPointF y2EndPoint(pointx + width, pointy);
- m_painter->drawLine(y2StartPoint, y2EndPoint); // 坐标轴y2高度为height
- // (2)获得数据并分析最大值与最小值
- DataInfo vectorX, vectorY1, vectorY2; // 数据储存在容器中,大小为POINTSNUM]
- // 模拟随机数据
- srand((int)time(NULL));
- vectorX.init();
- vectorY1.init();
- vectorY2.init();
- vectorX.print();
- vectorY1.print();
- vectorY2.print();
- double kx = (double)(width / vectorX.scaleRange); // x轴的系数
- double ky1 = (double)(height / vectorY1.scaleRange); // y1方向的比例系数
- double ky2 = (double)(height / vectorY2.scaleRange); // y2方向的比例系数
- // (3)绘制点
- QPen penPointY1, penPointY2;
- penPointY1.setColor(Qt::blue);
- penPointY1.setWidth();
- penPointY2.setColor(Qt::red);
- penPointY2.setWidth();
- for (int i = ; i < POINTSNUM; ++i)
- {
- double dXStart = pointx + kx * (vectorX.vecData[i] - vectorX.minScale);
- m_painter->setPen(penPointY1); // 蓝色的笔,用于标记Y1各个点
- m_painter->drawPoint(dXStart, pointy - (vectorY1.vecData[i] - vectorY1.minScale) * ky1);
- m_painter->setPen(penPointY2); // 红色的笔,用于标记Y2各个点
- m_painter->drawPoint(dXStart, pointy - (vectorY2.vecData[i] - vectorY2.minScale) * ky2);
- }
- // (4) 绘制刻度线
- QPen penDegree;
- penDegree.setColor(Qt::black);
- penDegree.setWidth();
- m_painter->setPen(penDegree);
- // x轴刻度线和值
- // x轴 第一个刻度值
- m_painter->drawText(pointx + , pointy + , QString::number(vectorX.minScale, 'f', ));
- for (int i = ; i < POINTSNUM - ; ++i) // 分成10份
- {
- // // 选取合适的坐标,绘制一段长度为4的直线,用于表示刻度
- // m_painter->drawLine(pointx + (i + 1) * width/10, pointy,
- // pointx + (i+1)*width/10, pointy + 4);
- m_painter->drawText(pointx + (i+0.9) * width / POINTSNUM, pointy + , // 值的位置信息
- QString::number(vectorX.minScale + (i+) * (vectorX.scaleRange/POINTSNUM), 'f', ));
- }
- // x轴 最后一个刻度值
- m_painter->drawText(pointx + (POINTSNUM - + 0.8) * width / POINTSNUM, pointy + ,
- QString::number(vectorX.maxScale, 'f', ));
- xStartPoint.setX(pointx);
- xStartPoint.setY(pointy + );
- xEndPoint.setX(pointx + width);
- xEndPoint.setY(pointy + );
- m_painter->drawLine(xStartPoint, xEndPoint);
- m_painter->drawText(pointx + width/, pointy + , QString("X"));
- // y1轴刻度线和值
- // y1轴 第一个刻度值
- m_painter->drawText(pointx - , pointy - , QString::number(vectorY1.minScale, 'f', ));
- for (int i = ; i < POINTSNUM - ; ++i)
- {
- // 代码较长,但是掌握基本原理即可。
- // 主要就是确定一个位置,然后画一条短短的直线表示刻度。
- // m_painter->drawLine(pointx, pointy-(i+1)*height/10,
- // pointx-4, pointy-(i+1)*height/10);
- m_painter->drawText(pointx - , pointy - (i+0.85) * height/POINTSNUM,
- QString::number(vectorY1.minScale + (i+) * (vectorY1.scaleRange/POINTSNUM), 'f', ));
- }
- // y1轴 最后一个刻度值
- m_painter->drawText(pointx - , pointy - (POINTSNUM - + 0.85) * height/POINTSNUM,
- QString::number(vectorY1.maxScale, 'f', ));
- y1StartPoint.setX(pointx - );
- y1StartPoint.setY(pointy - height);
- y1EndPoint.setX(pointx - );
- y1EndPoint.setY(pointy);
- m_painter->drawLine(y1StartPoint, y1EndPoint);
- m_painter->drawText(pointx - , pointy - height/, QString("Y1"));
- // y2轴刻度线和值
- // y2轴 第一个刻度值
- m_painter->drawText(pointx + width + , pointy - , QString::number(vectorY2.minScale, 'f', ));
- for (int i = ; i < POINTSNUM - ; ++i)
- {
- // m_painter->drawLine(pointx + width, pointy-(i+1)*height/10,
- // pointx + width + 4, pointy-(i+1)*height/10);
- m_painter->drawText(pointx + width + , pointy - (i+0.85)*height/POINTSNUM,
- QString::number((vectorY2.minScale + (i+)*(vectorY2.scaleRange/POINTSNUM)), 'f' , ));
- }
- // Y2轴 最后一个刻度值
- m_painter->drawText(pointx + width + , pointy - (POINTSNUM - + 0.85)*height/POINTSNUM,
- QString::number(vectorY2.maxScale, 'f', ));
- y2StartPoint.setX(pointx + width + );
- y2StartPoint.setY(pointy - height);
- y2EndPoint.setX(pointx + width + );
- y2EndPoint.setY(pointy);
- m_painter->drawLine(y2StartPoint, y2EndPoint);
- m_painter->drawText(pointx + width + , pointy - height/, QString("Y2"));
- // (5)绘制网格
- QPen penDotLine;
- penDotLine.setStyle(Qt::DotLine);
- m_painter->setPen(penDotLine);
- for (int i = ; i < POINTSNUM; ++i)
- {
- // 垂直线
- m_painter->drawLine(pointx + (i+)* width/POINTSNUM, pointy,
- pointx + (i+)* width/POINTSNUM, pointy - height);
- // 水平线
- m_painter->drawLine(pointx, pointy-(i+)*height/POINTSNUM,
- pointx + width, pointy-(i+)*height/POINTSNUM);
- }
- }
- MainWindow::~MainWindow()
- {
- delete ui;
- delete m_painter;
- }
- void MainWindow::paintEvent(QPaintEvent *)
- {
- QPainter painter(this);
- painter.drawImage(, , m_image);
- }
(5)main文件
- #include "mainwindow.h"
- #include <QApplication>
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- MainWindow w;
- w.show();
- return a.exec();
- }
【2】效果图
运行结果图如下:
Good Good Study, Day Day Up.
顺序 选择 循环 总结
利用QPainter绘制散点图的更多相关文章
- PyQt5利用QPainter绘制各种图形
这个例子我做了好几天: 1)官网C++的源码,改写成PyQt5版本的代码,好多细节不会转化 2)网上的PyQt的例子根本运行不了 填了无数个坑,结合二者,终于能完成了一个关于绘图的东西.这个过程也掌握 ...
- 利用QPainter绘制各种图形(Shape, Pen 宽带,颜色,风格,Cap,Join,刷子)
利用QPainter绘制各种图形 Qt的二维图形引擎是基于QPainter类的.QPainter既可以绘制几何形状(点.线.矩形.椭圆.弧形.弦形.饼状图.多边形和贝塞尔曲线),也可以绘制像素映射.图 ...
- 【带着canvas去流浪(4)】绘制散点图
目录 一. 任务说明 二. 重点提示 三. 示例代码 四.散点hover交互效果的实现 4.1 基本算法 4.2 参考代码 4.3 Demo中的小问题 示例代码托管在:http://www.githu ...
- 带着canvas去流浪系列之四 绘制散点图
[摘要] 用原生canvasAPI实现百度Echarts图表 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 任务说明 使用原生canvasAPI ...
- C#利用GDI+绘制旋转文字等效果
C#中利用GDI+绘制旋转文本的文字,网上有很多资料,基本都使用矩阵旋转的方式实现.但基本都只提及按点旋转,若要实现在矩形范围内旋转文本,资料较少.经过琢磨,可以将矩形内旋转转化为按点旋转,不过需要经 ...
- 利用PowerDesigner绘制PDM生成SQL Server数据库
PowerDesigner是个很强大的建模工具,可以利用它绘制各种图形,本文利用该工具绘制PDM,进而生成SQL Server数据库. 比如绘制一个简单的学生选课.教师授课管理系统的PDM: pk表示 ...
- 在OpenCV中利用鼠标绘制矩形和截取图像的矩形区域
这是两个相关的程序,前者是后者的基础.实际上前一个程序也是在前面博文的基础上做的修改,请参考<在OpenCV中利用鼠标绘制直线> .下面贴出代码. 程序之一,在OpenCV中利用鼠标绘制矩 ...
- 利用JFreeChart绘制股票K线图完整解决方案
http://blog.sina.com.cn/s/blog_4ad042e50100q7d9.html 利用JFreeChart绘制股票K线图完整解决方案 (2011-04-30 13:27:17) ...
- Python使用Plotly绘图工具,绘制散点图、线形图
今天在研究Plotly绘制散点图的方法 使用Python3.6 + Plotly Plotly版本2.0.0 在开始之前先说说,还需要安装库Numpy,安装方法在我的另一篇博客中有写到:https:/ ...
随机推荐
- Javascript 面向对象编程(一):封装 作者:yuan一峰
学习Javascript,最难的地方是什么? 我觉得,Object(对象)最难.因为Javascript的Object模型很独特,和其他语言都不一样,初学者不容易掌握. 下面就是我的学习笔记,希望对大 ...
- shell 变量的数值计算实践 expr
expr(evaluate(求值)expressions(表达式))命令既可以用于整数运算,也可以用于相关字符串长度.匹配等的运算处理 expr 用做计算 必须有一个空格才会计算 [root@salt ...
- Linux 磁盘空间大小统计du命令常见使用方法
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/hongweigg/article/details/37692057 在 Linux下,能够对某个文件 ...
- 怎样打开U盘最安全
为了避免电脑使用U盘时,通过双击,或者右击盘符时,导致把病毒感染至整个电脑,因此使用下面的方法,可使U盘病毒不被激活传播. 在取消了U盘自动运行的情况下(在组策略中一定要关闭自动运行功能,否则只要一插 ...
- jsp fmt标签格式化double数字
<fmt:formatNumber value="${zjdl.ygdl }" pattern="0.00" />
- K-means &K-medoids 聚类
k-平均值算法对孤立点很敏感!因为具有特别大的值的对象可能显著地影响数据的分布. k-中心点(k-Medoids): 不采用簇中对象的平均值作为参照点, 而是选用簇中位置最中心的对象, 即中心点(me ...
- linux下automake用法
linux下automake用法 2017年02月06日 09:21:14 阅读数:3684 标签: makemakefilegnulinux 作为Linux下的程序开发人员,大家一定都遇到过Ma ...
- 创建vue项目的时候遇到:PhantomJS not found on PATH
1.提示找不到PhantomJS需要进行下载,如果网速允许的话可以直接 npm install -g phantomjs 如果网速不给力的话,那就先进行淘宝镜像安装 npm install -g cn ...
- Linux个人知识扩展:服务器几u的意思,网络带宽
服务器几u的意思: 指的服务器大小规格 1U=4.45cm 2U=8.9cm 3U=4.45cm * 3 4U=4.45cm * 4 这指的是服务器的高度 现在的服务器为节省空间都是很扁的 U是服务器 ...
- jenkins 多选参数构建配置
参考:https://blog.csdn.net/e295166319/article/details/54017231 场景: 有的时候,参数基本都是那几个,但是不变,但是参数名字比较长,不好记忆, ...