【QCustomPlot】绘制 x-y 曲线图

这篇具有很好参考价值的文章主要介绍了【QCustomPlot】绘制 x-y 曲线图。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

说明

使用 QCustomPlot 绘图库辅助开发时整理的学习笔记。同系列文章目录可见 《绘图库 QCustomPlot 学习笔记》目录。本篇介绍如何使用 QCustomPlot 绘制 x-y 曲线图,需要 x 轴数据与 y 轴数据都已知,示例中使用的 QCustomPlot 版本为 Version 2.1.1,QT 版本为 5.9.2

目录
  • 说明
  • 1. 示例工程配置
  • 2. 常用 API 介绍
  • 3. 绘制一条 x-y 曲线
  • 4. 绘制多条 x-y 曲线
  • 5. 绘制往回走的 x-y 曲线
    • 5.1 靠谱方法:互换 x-y 轴
    • 5.2 偷懒方法:设置 alreadySorted = true
    • 5.3 备用方法:导出绘图数据内存地址
  • 6. 绘制间隙中断的 x-y 曲线

1. 示例工程配置

通过包含源码的方式来使用 QCustomPlot 绘图库,方法详见本人同系列文章 使用方法(源码方式)。此外,库官网有提供绘图的示例代码,详见 QCustomPlot - Introduction,下载压缩包 QCustomPlot.tar.gz 中也有示例的工程代码,详见同系列文章 下载。下面示例中所用的工程文件(demoQCP.pro)内容为:

QT       += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport

greaterThan(QT_MAJOR_VERSION, 4): CONFIG += c++11
lessThan(QT_MAJOR_VERSION, 5): QMAKE_CXXFLAGS += -std=c++11

TARGET = demoQCP
TEMPLATE = app

SOURCES += main.cpp\
           qcustomplot.cpp

HEADERS  += qcustomplot.h

实际使用 QCustomPlot 进行绘图时,通常是将 UI 界面中的某个 QWidget 控件提升为 QCustomPlot,然后以指针的方式调用 QCustomPlot 的类方法绘制图像。这一方式用在示例中有点繁琐(需要 .ui 文件),为了突出示例重点,减少文件依赖,示例代码直接在 main.cpp 中声明了一个 QCustomPlot 对象,示例工程所需的文件如下,只需四个文件,demoQCP.pro 的文件内容已在上面给出,main.cpp 的文件内容会在后面给出,qcustomplot.hqcustomplot.cpp 两个文件下载自官网。

【QCustomPlot】绘制 x-y 曲线图

main.cpp 文件的框架如下,demoPlot() 里面用来写绘图的示例代码。

#include <QApplication>
#include <QMainWindow>
#include "qcustomplot.h"

void demoPlot(QCustomPlot *customPlot)
{
    // 绘图示例代码
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QMainWindow window;

    // 将QCustomPlot窗口作为QMainWindow中心窗口
    QCustomPlot customPlot;
    window.setCentralWidget(&customPlot);

    // 绘图
    demoPlot(&customPlot);

    // 显示
    window.setWindowTitle(QStringLiteral("x-y 曲线图示例 @木三百川"));
    window.setGeometry(100, 100, 800, 600);
    window.show();

    return a.exec();
}

关于绘图颜色、线型、字体、网格线等外观上的美化,会在本人同系列文章 《绘图库 QCustomPlot 学习笔记》目录 中再做介绍,想学习的不妨关注一下。本文章只介绍绘制 x-y 曲线图的基础方法。

2. 常用 API 介绍

绘制 x-y 曲线图所使用的类为 QCPGraph,它提供的类方法可在 Documentation - QCPGraph 中找到。常用的接口有以下几个:

// 重置/添加绘图数据的接口
void setData(const QVector<double> &keys, const QVector<double> &values, bool alreadySorted=false)
void addData(const QVector<double> &keys, const QVector<double> &values, bool alreadySorted=false)
void addData(double key, double value)
    
// 设置线型
void setLineStyle(LineStyle ls)
    
// 设置点型
void setScatterStyle(const QCPScatterStyle &style)

3. 绘制一条 x-y 曲线

demoPlot() 函数如下:

void demoPlot(QCustomPlot *customPlot)
{
    // 显示上方横轴(xAxis2)与右方纵轴(yAxis2),并与xAxis/yAxis保持同步
    customPlot->axisRect()->setupFullAxesBox(true);
    
    // 生成x-y数据, y=x^2, 定义域[-1,1]
    QVector<double> x(101), y(101);
    for (int i = 0; i < 101; ++i)
    {
        x[i] = i/50.0 - 1;
        y[i] = x[i]*x[i];
    }
    
    // 新建QCPGraph对象,并设置绘图数据
    customPlot->addGraph();
    customPlot->graph(0)->setData(x, y);
    
    // 设置标题
    customPlot->plotLayout()->insertRow(0);
    customPlot->plotLayout()->addElement(0, 0, new QCPTextElement(customPlot, "Test-Title", QFont("sans", 17, QFont::Bold)));
    
    // 设置坐标轴标签
    customPlot->xAxis->setLabel("x");
    customPlot->yAxis->setLabel("y");
    
    // 设置坐标轴范围
    customPlot->xAxis->setRange(-1, 1);
    customPlot->yAxis->setRange(0, 1);
    
    // 刷新显示
    customPlot->replot();
}

绘制效果:

【QCustomPlot】绘制 x-y 曲线图

4. 绘制多条 x-y 曲线

demoPlot() 函数如下:

void demoPlot(QCustomPlot *customPlot)
{
    // 显示上方横轴(xAxis2)与右方纵轴(yAxis2),并与xAxis/yAxis保持同步
    customPlot->axisRect()->setupFullAxesBox(true);

    // 生成x-y数据,y1=x^2,y2=x^3,定义域[-1,1]
    QVector<double> x(101), y1(101), y2(101);
    for (int i = 0; i < 101; ++i)
    {
        x[i] = i/50.0 - 1;
        y1[i] = x[i]*x[i];
        y2[i] = x[i]*x[i]*x[i];
    }

    // 新建QCPGraph对象,并设置绘图数据x-y1
    customPlot->addGraph();
    customPlot->graph(0)->setPen(QPen(Qt::blue));
    customPlot->graph(0)->setData(x, y1);
    customPlot->graph(0)->setName(QStringLiteral("二次曲线图例"));

    // 新建QCPGraph对象,并设置绘图数据x-y2
    customPlot->addGraph();
    customPlot->graph(1)->setPen(QPen(Qt::red));
    customPlot->graph(1)->setData(x, y2);
    customPlot->graph(1)->setName(QStringLiteral("三次曲线图例"));

    // 显示图例
    customPlot->legend->setVisible(true);

    // 设置标题
    customPlot->plotLayout()->insertRow(0);
    customPlot->plotLayout()->addElement(0, 0, new QCPTextElement(customPlot, "Test-Title", QFont("sans", 17, QFont::Bold)));

    // 设置坐标轴标签
    customPlot->xAxis->setLabel("x");
    customPlot->yAxis->setLabel("y");

    // 设置坐标轴范围
    customPlot->xAxis->setRange(-1, 1);
    customPlot->yAxis->setRange(-1, 1);

    // 刷新显示
    customPlot->replot();
}

绘制效果:

【QCustomPlot】绘制 x-y 曲线图

5. 绘制往回走的 x-y 曲线

举个例子,若需要绘制 \(x=(y+0.8)\times y\times (y-0.8),y\in [-1,1]\) 曲线,有三种方法:

  • 方法一:新建 QCPGraph 对象时,指定 yAxiskeyAxis,指定 xAxisvalueAxis,即互换一下坐标轴的角色,这是最靠谱也最常用的方法。
  • 方法二:仍以 xAxiskeyAxisyAxisvalueAxis(默认情况),但在调用 setData() 时,需传入第三个参数 true。这是一种偷懒的做法,并且绘图的横轴数据(keyAxis)需满足一定的条件:keyData 必须先递增再减小、且减小时不得离 keyData[0] 太近,否则绘图会出错。
  • 方法三:导出绘图数据的内存地址,直接将数据写入内存中,这种做法常被用来提升 QCustomPlot 性能,缩短数据更新时间,但用此来绘制往回走的 x-y 曲线时,绘图的横轴数据也需要满足上面的条件,否则绘图会出错。

当曲线形成的环路很复杂时,一般采用绘制参数曲线的方法来表现,详见 Documentation - QCPCurve 或本人同系列文章。

5.1 靠谱方法:互换 x-y 轴

demoPlot() 函数如下:

void demoPlot(QCustomPlot *customPlot)
{
    // 显示上方横轴(xAxis2)与右方纵轴(yAxis2),并与xAxis/yAxis保持同步
    customPlot->axisRect()->setupFullAxesBox(true);

    // 生成y-x数据, x=(y+0.8)*y*(y-0.8), 定义域[-1,1]
    QVector<double> x(101), y(101);
    for (int i = 0; i < 101; ++i)
    {
        y[i] = i/50.0 - 1;
        x[i] = (y[i]+0.8)*y[i]*(y[i]-0.8);
    }

    // 新建QCPGraph对象(互换xAxis/yAxis),并设置绘图数据
    customPlot->addGraph(customPlot->yAxis, customPlot->xAxis);
    customPlot->graph(0)->setData(y, x);

    // 设置标题
    customPlot->plotLayout()->insertRow(0);
    customPlot->plotLayout()->addElement(0, 0, new QCPTextElement(customPlot, "Test-Title", QFont("sans", 17, QFont::Bold)));

    // 设置坐标轴标签
    customPlot->xAxis->setLabel("x");
    customPlot->yAxis->setLabel("y");

    // 设置坐标轴范围
    customPlot->xAxis->setRange(-0.5, 0.5);
    customPlot->yAxis->setRange(-1, 1);

    // 刷新显示
    customPlot->replot();
}

绘制效果:

【QCustomPlot】绘制 x-y 曲线图

5.2 偷懒方法:设置 alreadySorted = true

demoPlot() 函数如下:

void demoPlot(QCustomPlot *customPlot)
{
    // 显示上方横轴(xAxis2)与右方纵轴(yAxis2),并与xAxis/yAxis保持同步
    customPlot->axisRect()->setupFullAxesBox(true);

    // 生成y-x数据, x=(y+0.8)*y*(y-0.8), 定义域[-1,1]
    QVector<double> x(101), y(101);
    for (int i = 0; i < 101; ++i)
    {
        y[i] = i/50.0 - 1;
        x[i] = (y[i]+0.8)*y[i]*(y[i]-0.8);
    }

    // 新建QCPGraph对象,并设置绘图数据以及 alreadySorted = true
    customPlot->addGraph();
    customPlot->graph(0)->setData(x, y, true);

    // 设置标题
    customPlot->plotLayout()->insertRow(0);
    customPlot->plotLayout()->addElement(0, 0, new QCPTextElement(customPlot, "Test-Title", QFont("sans", 17, QFont::Bold)));

    // 设置坐标轴标签
    customPlot->xAxis->setLabel("x");
    customPlot->yAxis->setLabel("y");

    // 设置坐标轴范围
    customPlot->xAxis->setRange(-0.5, 0.5);
    customPlot->yAxis->setRange(-1, 1);

    // 刷新显示
    customPlot->replot();
}

绘制效果:

【QCustomPlot】绘制 x-y 曲线图

注意这张图中,keyData (横轴)满足先递增再减小、且减小时的最小值(约为 -0.197)大于 keyData[0](约为 -0.360),所以绘制没有出错。有兴趣的可以尝试一下,当横轴数据减小且比较接近 keyData[0] 时,绘制的效果。

5.3 备用方法:导出绘图数据内存地址

关于如何导出一维绘图数据的内存地址,详见本人另一篇文章 【QCustomPlot】性能提升之修改源码(版本 V2.x.x)。demoPlot() 函数如下:

void demoPlot(QCustomPlot *customPlot)
{
    // 显示上方横轴(xAxis2)与右方纵轴(yAxis2),并与xAxis/yAxis保持同步
    customPlot->axisRect()->setupFullAxesBox(true);

    // 新建QCPGraph对象,获得绘图数据的内存地址,并设置绘图数据
    customPlot->addGraph();
    QVector<QCPGraphData> *mData = customPlot->graph(0)->data()->coreData();
    mData->reserve(101);
    mData->resize(101);
    for (int i = 0; i < 101; ++i)
    {
        double y = i/50.0 - 1;
        (*mData)[i].key = (y+0.8)*y*(y-0.8);
        (*mData)[i].value = y;
    }

    // 设置标题
    customPlot->plotLayout()->insertRow(0);
    customPlot->plotLayout()->addElement(0, 0, new QCPTextElement(customPlot, "Test-Title", QFont("sans", 17, QFont::Bold)));

    // 设置坐标轴标签
    customPlot->xAxis->setLabel("x");
    customPlot->yAxis->setLabel("y");

    // 设置坐标轴范围
    customPlot->xAxis->setRange(-0.5, 0.5);
    customPlot->yAxis->setRange(-1, 1);

    // 刷新显示
    customPlot->replot();
}

绘制效果:

【QCustomPlot】绘制 x-y 曲线图

6. 绘制间隙中断的 x-y 曲线

keyAxis 数据中存在 NaN 时,绘制曲线会出现间隙中断的效果,demoPlot() 函数如下:

void demoPlot(QCustomPlot *customPlot)
{
    // 显示上方横轴(xAxis2)与右方纵轴(yAxis2),并与xAxis/yAxis保持同步
    customPlot->axisRect()->setupFullAxesBox(true);

    // 生成x-y数据, y=x^2, 定义域[-1,1]
    QVector<double> x(101), y(101);
    for (int i = 0; i < 101; ++i)
    {
        x[i] = i/50.0 - 1;
        y[i] = x[i]*x[i];
    }
    y[30] = qQNaN();
    y[60] = std::numeric_limits<double>::quiet_NaN();

    // 新建QCPGraph对象,并设置绘图数据
    customPlot->addGraph();
    customPlot->graph(0)->setData(x, y);

    // 设置标题
    customPlot->plotLayout()->insertRow(0);
    customPlot->plotLayout()->addElement(0, 0, new QCPTextElement(customPlot, "Test-Title", QFont("sans", 17, QFont::Bold)));

    // 设置坐标轴标签
    customPlot->xAxis->setLabel("x");
    customPlot->yAxis->setLabel("y");

    // 设置坐标轴范围
    customPlot->xAxis->setRange(-1, 1);
    customPlot->yAxis->setRange(0, 1);

    // 刷新显示
    customPlot->replot();
}

绘制效果:

【QCustomPlot】绘制 x-y 曲线图文章来源地址https://www.toymoban.com/news/detail-490930.html

到了这里,关于【QCustomPlot】绘制 x-y 曲线图的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Qt绘制曲线图(基于qt画图QPainter)

    在没有QCharst模块时,可以使用QPainter自定义绘制曲线折线图 下面提供完整代码供参考: 直接在qt创建一个QMainWindow类的app的工程,不自动生成ui文件,然后把下面代码复制到mainwindow.cpp编译运行即可。 mainwindow.cpp: //博客:booinon //https://blog.csdn.net/boonion?spm=1011.2415.3001.5343

    2024年02月11日
    浏览(46)
  • QT图表-折线图、曲线图

    时间记录:2024/1/15 1.添加图表模块 .pro项目管理文件中添加charts模块 QChart类:图表类 QChartView类:图表显示类 2.ui文件中添加QChartView组件 (1)选择一个QGrapicsView组件将其拖拽到ui界面上合适位置 (2)右键新添加的QGrapicsView组件,将组件提升为QChartView组件 3.添加QChartView类的命

    2024年01月18日
    浏览(46)
  • 98.qt qml-使用曲线图综合示例、支持多种鼠标交互、支持百万数据显示(已适配黑白风格)

    在上章我们只是简单实现了曲线图和折线图的显示: 79.qt qml-如何在QML中使用QCustomPlot之曲线/折线示例(已适配黑白风格)_qml 折线图_诺谦的博客-CSDN博客 所以本章实现综合示例、并添加多种功能如下所示: 详细显示:鼠标任意移动显示具体值内容 鼠标右击: 弹出菜单栏,支持

    2024年02月05日
    浏览(63)
  • YOLOv5|YOLOv7|YOLOv8改进之实验结果(四):将多种算法的Loss精度曲线图绘制到一张图上,便于YOLOv5、v7系列模型对比实验获取更多精度数据,丰富实验数据

    💡该教程为改进YOLO高阶指南,属于 《芒果书》 📚系列,包含大量的原创首发改进方式🚀 💡更多改进内容📚可以点击查看:YOLOv5改进、YOLOv7改进、YOLOv8改进、YOLOX改进原创目录 | 老师联袂推荐🏆 💡 🚀🚀🚀本博客内含·改进源代码·,按步骤操作运行改进后的代码即可

    2023年04月17日
    浏览(54)
  • Qt+C++串口调试接收发送数据曲线图

    程序示例精选 Qt+C++串口调试接收发送数据曲线图 如需安装运行环境或远程调试,见文章底部个人 QQ 名片,由专业技术人员远程协助! 这篇博客针对Qt+C++串口调试接收发送数据曲线图编写代码,代码整洁,规则,易读。 学习与应用推荐首选。 一、所需工具软件 二、使用步骤

    2024年02月11日
    浏览(49)
  • 【KV260】利用XADC生成芯片温度曲线图

    如何在没有温度计的情况下,监控芯片的温度呢? Xilinx不仅提供了内置的XADC来观察温度,而且还可以生成如下的曲线图 具体操作如下 这时可以看到当前温度,最小温度,最大温度 上面是直接读取温度值。如果我们要长时间观察温度变化情况怎么办呢? 如下图 在黑色曲线区

    2024年02月15日
    浏览(41)
  • echarts折线图流动特效的实现(非平滑曲线)

    echarts官网:series-lines 注意:流动特效只支持非平滑曲线(smooth:false) series-lines路径图 : 用于带有起点和终点信息的线数据的绘制,主要用于地图上的航线,路线的可视化。 ECharts 2.x 里会用地图上的 markLine 去绘制迁徙效果,在 ECharts 3 里建议使用单独的 lines 类型图表。

    2024年02月14日
    浏览(44)
  • 基于IMX6ULL的AP3216C的QT动态数据曲线图显示

    前言: 本文为手把手教学 Linux+QT 的典型基础项目 AP3216C 的数据折线图显示,项目使用正点原子的 IMX6ULL  阿尔法( Cortex-A7 系列)开发板。项目需要实现 AP3216C 在 Linux 系统下的驱动,使用 QT 设计 AP3216C 的数据显示页面作为项目的应用层。该项目属于非常简单的入门级项目,核心

    2024年02月16日
    浏览(50)
  • vue2.x-echarts公共组件封装--简易篇(3d柱状图,炫酷仪表盘,折线,曲线图)

    更新一下之前写的echarts简单图表公共组件的封装,该组件可以实现自适应展示效果 废话不多说,上代码: vue-echarts通用组件 下面的一个混入文件是用来实现,窗口改变echarts自适应的js文件: 接下来是debounce.js 下面直接上代码:父组件调用+展示效果 截图: 下面是一个仪表盘

    2023年04月13日
    浏览(72)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包