QCustomPlot绘图类详解(大白话)

news2024/11/24 6:49:41

本文假定你会使用Qt开发,但未接触过QCustomPlot绘图类或者是刚接触。

如何往Qt中引入QCustomPlot

  1. 首先,去官网下载最新版本的源码,注意是QCustomPlot.tar.gz这个文件,里面包含源码和示例。实际上,我们只需要qcustomplot.hqcustomplot.h这两个源文件。
    官网下载
  2. 将代码文件拷贝到本地工程,并引入。
    引入源文件
    QCustomPlot需要依赖printsupport模块,如果你是使用QT+VS开发,配置如下:
    Qt+Vs
    如果是Qt Create开发,在.pro文件中添加:QT += QWidget printsupport
  3. 在Qt中新建ui文件,拖拽一个QWidget控件,将其提升为QCustomPlot
    在这里插入图片描述

QCustomPlot常用函数

// 设置背景色
ui.plotWidget->setBackground(QBrush(QColor("#404040")));

// 设置X/Y轴的标签
ui.plotWidget->xAxis->setLabel(QStringLiteral("次数"));

// 设置X/Y轴标签字体
ui.plotWidget->xAxis->setLabelFont(plotFont);

// 设置X/Y轴标签颜色
ui.plotWidget->xAxis->setLabelColor(QColor(Qt::red));

// 设置x=0或y=0所在直线的画笔
ui.plotWidget->xAxis->grid()->setZeroLinePen(QPen(QColor(Qt::yellow)));

// 设置X/Y轴刻度范围
ui.plotWidget->xAxis->setRange(1, PT_CNT);

// 设置X/Y轴刻度数,也就是分为几段
ui.plotWidget->xAxis->ticker()->setTickCount(8);

// 设置X/Y轴刻度值文本的颜色
ui.plotWidget->xAxis->setTickLabelColor(QColor(Qt::green));

// 设置X/Y轴轴线的画笔
ui.plotWidget->xAxis->setBasePen(QPen(QColor(Qt::white), 2, Qt::SolidLine));

// 设置X/Y轴大刻度的画笔,被分段的位置
ui.plotWidget->xAxis->setTickPen(QPen(QColor("#ff00ff")));

// 设置X/Y轴小刻度的画笔
ui.plotWidget->xAxis->setSubTickPen(QPen(QColor("#00ffff")));

// 设置内部网格线的画笔
ui.plotWidget->xAxis->grid()->setPen(QPen(QColor(Qt::darkRed), 1, Qt::DotLine));

// 添加一个图层
ui.plotWidget->addGraph();

// 为对应图层添加数据
ui.plotWidget->graph(0)->addData(keys, values);

// 为图层设置画笔
ui.plotWidget->graph(0)->setPen(QColor(Qt::blue));

// 设置是/否抗锯齿
ui.plotWidget->graph(0)->setAntialiasedFill(true);

// 刷新绘图,更改数据后需手动刷新(缩放会自动刷新)
ui.plotWidget->replot();

// 支持拖拽和缩放
ui.plotWidget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);

绘制直方图

更改QCustomPlot相关属性,这里以颜色修改为主(稍有点乱哈),创建距离-测距次数的直方图。
在这里插入图片描述
相关代码如下:

void PlotTest::InitForm()
{
    ui.plotWidget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);

    ui.plotWidget->setBackground(QBrush(QColor("#404040")));
    ui.plotWidget->xAxis->setLabel(QStringLiteral("次数"));
    ui.plotWidget->yAxis->setLabel(QStringLiteral("距离(cm)"));

    QFont plotFont = font();
    plotFont.setPointSizeF(10.0);

    ui.plotWidget->xAxis->setLabelFont(plotFont);
    ui.plotWidget->yAxis->setLabelFont(plotFont);
    ui.plotWidget->xAxis->setLabelColor(QColor(Qt::red));
    ui.plotWidget->yAxis->setLabelColor(QColor(Qt::red));
    ui.plotWidget->xAxis->grid()->setZeroLinePen(QPen(QColor(Qt::yellow)));
    ui.plotWidget->yAxis->grid()->setZeroLinePen(QPen(QColor(Qt::yellow)));
    ui.plotWidget->xAxis->setRange(1, PT_CNT);
    ui.plotWidget->yAxis->setRange(-10, 90);
    ui.plotWidget->xAxis->ticker()->setTickCount(8);
    ui.plotWidget->yAxis->ticker()->setTickCount(8);
    ui.plotWidget->xAxis->setTickLabelColor(QColor(Qt::green));
    ui.plotWidget->yAxis->setTickLabelColor(QColor(Qt::green));
    ui.plotWidget->xAxis->setBasePen(QPen(QColor(Qt::white), 2, Qt::SolidLine));
    ui.plotWidget->yAxis->setBasePen(QPen(QColor(Qt::white), 2, Qt::SolidLine));
    ui.plotWidget->xAxis->setTickPen(QPen(QColor("#ff00ff")));
    ui.plotWidget->yAxis->setTickPen(QPen(QColor("#ff00ff")));
    ui.plotWidget->xAxis->setSubTickPen(QPen(QColor("#00ffff")));
    ui.plotWidget->yAxis->setSubTickPen(QPen(QColor("#00ffff")));
    ui.plotWidget->xAxis->grid()->setPen(QPen(QColor(Qt::darkRed), 1, Qt::DotLine));
    ui.plotWidget->yAxis->grid()->setPen(QPen(QColor(Qt::darkGreen), 1, Qt::DotLine));

    QVector<double> keys, values;
    for (int i = 1; i <= PT_CNT; i++)
    {
        keys.push_back(i);
        values.push_back(rand() % 100 - 10);
    }
    ui.plotWidget->addGraph();
    ui.plotWidget->graph(0)->addData(keys, values);
    ui.plotWidget->graph(0)->setPen(QColor(Qt::blue));
    ui.plotWidget->graph(0)->setAntialiasedFill(true);
    ui.plotWidget->replot();
}

刷新直方图

刷新直方图比较简单,刷新指定图层的数据即可。有2种方式:

  • 更换数据
ui.plotWidget->graph(0)->data()->clear(); // 清楚图层对应的数据
ui.plotWidget->graph(0)->addData(keys, values); // 添加新的数据
  • 更换图层
ui.plotWidget->clearGraphs(); // 删除图层(单个或所有)
ui.plotWidget->addGraph(); // 新建图层
ui.plotWidget->graph(0)->addData(keys, values); // 添加新数据

注:两种方式会适用于不同的场景下。
请添加图片描述

绘制连续的直方图

连续直方图可以理解为:不断往图层里添加数据。需要注意的是,每次添加数据都需要更新刻度范围。代码如下:

void PlotTest::DrawContinueGraph()
{
    QVector<double> keys, values;

    for (int i = 1; i <= PT_CNT; i++)
    {
        keys.push_back(mRefreshCnt * PT_CNT + i);
        values.push_back(rand() % 100 + 1);
    }

    ui.plotWidget->graph(0)->addData(keys, values);
    ui.plotWidget->xAxis->setRange(1, PT_CNT * (mRefreshCnt + 1));
    ui.plotWidget->graph(0)->setAntialiasedFill(true);
    ui.plotWidget->replot();

    mRefreshCnt++;
}

请添加图片描述

完整代码

// PlotTest.h文件
#pragma once

#include <QtWidgets/QWidget>
#include "ui_PlotTest.h"

class PlotTest : public QWidget
{
    Q_OBJECT

public:
    PlotTest(QWidget *parent = nullptr);
    ~PlotTest();

public:
    void InitForm();            // 初始化控件
    void DrawStaticGraph();     // 绘制静态库
    void DrawDynamicGraph();    // 绘制动态库(单图刷新)
    void DrawContinueGraph();   // 绘制连续图(多图刷新)
    
public slots:
    void on_btnDynamicDraw_clicked();
    void on_btnContinueDraw_clicked();

private:
    Ui::PlotTestClass ui;
    int mRefreshCnt; // 连续刷新次数
};
// PlotTest.cpp文件
#include "PlotTest.h"
#include "CustomPlot\qcustomplot.h"

#define PT_CNT       200    // 点数
#define GRAPH_CNT    5      // 图数

PlotTest::PlotTest(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);

    InitForm();
    mRefreshCnt = 1;
}

PlotTest::~PlotTest()
{

}

void PlotTest::on_btnDynamicDraw_clicked()
{
    ui.btnDynamicDraw->setEnabled(false);
    ui.btnContinueDraw->setEnabled(false);
    mRefreshCnt = 1;

    for (int i = 0; i < 10; i++)
    {
        DrawDynamicGraph();
        Sleep(500);
    }

    ui.btnDynamicDraw->setEnabled(true);
    ui.btnContinueDraw->setEnabled(true);
}

void PlotTest::on_btnContinueDraw_clicked()
{
    ui.btnDynamicDraw->setEnabled(false);
    ui.btnContinueDraw->setEnabled(false);
    mRefreshCnt = 0;
    ui.plotWidget->graph(0)->data()->clear();
    ui.plotWidget->xAxis->setRange(1, PT_CNT);

    for (int i = 0; i < 10; i++)
    {
        DrawContinueGraph();
        Sleep(500);
    }

    ui.btnDynamicDraw->setEnabled(true);
    ui.btnContinueDraw->setEnabled(true);
}

void PlotTest::InitForm()
{
    ui.plotWidget->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);

#if 0
    ui.plotWidget->setBackground(QBrush(QColor("#404040")));
    ui.plotWidget->xAxis->setLabel(QStringLiteral("次数"));
    ui.plotWidget->yAxis->setLabel(QStringLiteral("距离(cm)"));

    QFont plotFont = font();
    plotFont.setPointSizeF(10.0);

    ui.plotWidget->xAxis->setLabelFont(plotFont);
    ui.plotWidget->yAxis->setLabelFont(plotFont);
    ui.plotWidget->xAxis->setLabelColor(QColor(Qt::red));
    ui.plotWidget->yAxis->setLabelColor(QColor(Qt::red));
    ui.plotWidget->xAxis->grid()->setZeroLinePen(QPen(QColor(Qt::yellow)));
    ui.plotWidget->yAxis->grid()->setZeroLinePen(QPen(QColor(Qt::yellow)));
    ui.plotWidget->xAxis->setRange(1, PT_CNT);
    ui.plotWidget->yAxis->setRange(-10, 90);
    ui.plotWidget->xAxis->ticker()->setTickCount(8);
    ui.plotWidget->yAxis->ticker()->setTickCount(8);
    ui.plotWidget->xAxis->setTickLabelColor(QColor(Qt::green));
    ui.plotWidget->yAxis->setTickLabelColor(QColor(Qt::green));
    ui.plotWidget->xAxis->setBasePen(QPen(QColor(Qt::white), 2, Qt::SolidLine));
    ui.plotWidget->yAxis->setBasePen(QPen(QColor(Qt::white), 2, Qt::SolidLine));
    ui.plotWidget->xAxis->setTickPen(QPen(QColor("#ff00ff")));
    ui.plotWidget->yAxis->setTickPen(QPen(QColor("#ff00ff")));
    ui.plotWidget->xAxis->setSubTickPen(QPen(QColor("#00ffff")));
    ui.plotWidget->yAxis->setSubTickPen(QPen(QColor("#00ffff")));
    ui.plotWidget->xAxis->grid()->setPen(QPen(QColor(Qt::darkRed), 1, Qt::DotLine));
    ui.plotWidget->yAxis->grid()->setPen(QPen(QColor(Qt::darkGreen), 1, Qt::DotLine));

    QVector<double> keys, values;
    for (int i = 1; i <= PT_CNT; i++)
    {
        keys.push_back(i);
        values.push_back(rand() % 100 - 10);
    }
    ui.plotWidget->addGraph();
    ui.plotWidget->graph(0)->addData(keys, values);
    ui.plotWidget->graph(0)->setPen(QColor(Qt::blue));
    ui.plotWidget->graph(0)->setAntialiasedFill(true);
    ui.plotWidget->replot();
#else
    ui.plotWidget->xAxis->setLabel(QStringLiteral("次数"));
    ui.plotWidget->yAxis->setLabel(QStringLiteral("距离(cm)"));
    ui.plotWidget->xAxis->setRange(1, PT_CNT);
    ui.plotWidget->yAxis->setRange(1, 100);
    ui.plotWidget->xAxis->ticker()->setTickCount(8);
    ui.plotWidget->yAxis->ticker()->setTickCount(8);

    DrawStaticGraph();

#endif
}

void PlotTest::DrawStaticGraph()
{
    QVector<double> keys, values;
    for (int i = 1; i <= PT_CNT; i++)
    {
        keys.push_back(i);
        values.push_back(rand() % 100 + 1);
    }

    ui.plotWidget->addGraph();
    ui.plotWidget->graph(0)->addData(keys, values);
    ui.plotWidget->graph(0)->setPen(QColor(Qt::blue));
    ui.plotWidget->graph(0)->setAntialiasedFill(true);
    ui.plotWidget->replot();
}

void PlotTest::DrawDynamicGraph()
{
    ui.plotWidget->clearGraphs();
    QVector<double> keys, values;
    for (int i = 1; i <= PT_CNT; i++)
    {
        keys.push_back(i);
        values.push_back(rand() % 100 + 1);
    }

    ui.plotWidget->addGraph();
    ui.plotWidget->graph(0)->addData(keys, values);
    ui.plotWidget->xAxis->setRange(1, PT_CNT);
    ui.plotWidget->graph(0)->setAntialiasedFill(true);
    ui.plotWidget->replot();
}

void PlotTest::DrawContinueGraph()
{
    QVector<double> keys, values;

    for (int i = 1; i <= PT_CNT; i++)
    {
        keys.push_back(mRefreshCnt * PT_CNT + i);
        values.push_back(rand() % 100 + 1);
    }

    ui.plotWidget->graph(0)->addData(keys, values);
    ui.plotWidget->xAxis->setRange(1, PT_CNT * (mRefreshCnt + 1));
    ui.plotWidget->graph(0)->setAntialiasedFill(true);
    ui.plotWidget->replot();

    mRefreshCnt++;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1009949.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Hadoop-Hive

1. hive安装部署 2. hive基础 3. hive高级查询 4. Hive函数及性能优化 1.hive安装部署 解压tar -xvf ./apache-hive-3.1.2-bin.tar.gz -C /opt/soft/ 改名mv apache-hive-3.1.2-bin/ hive312 配置环境变量&#xff1a;vim /etc/profile #hive export HIVE_HOME/opt/soft/hive…

【深度学习 AIGC】stablediffusion-infinity 在无界限画布中输出绘画 Outpainting

代码&#xff1a;https://github.com/lkwq007/stablediffusion-infinity/tree/master 启动环境&#xff1a; git clone --recurse-submodules https://github.com/lkwq007/stablediffusion-infinity cd stablediffusion-infinity conda env create -f environment.yml conda …

笔记(三)传统图机器学习的特征工程-节点

1、不同种类的任务 2、传统图机器学习的几个层面 &#xff08;人工特征工程机器学习&#xff09; 3、属性特征-节点本身的特征 4、连接特征-节点的结构信息 5、训练-预测 6、好模型需要好数据 -人工构造的特征&#xff08;特征工程&#xff09;-节点、连接、全图-无向图 7、节…

算法训练 第二周

一、赎金信 本题给出了两个字符串ransomNote和magazine&#xff0c;需要让我们判断ransomNote中的字符能不能由magazine中的字符构成&#xff0c;也就是说我们需要将所有ransomNote中的字符找到一个在magazine中与这个字符相同的字符&#xff0c;且每个字符只能使用一次&#x…

openssl websockets

1. HTTPS通信的C实现 - 知乎

【干货】Anaconda导出环境配置文件

【干货 | 项目导出安装环境要求】 方法yml文件req.txt文件 参考 方法 yml文件 激活虚拟环境&#xff08;fyp是我的虚拟环境名称&#xff0c;请根据你自己的名称进行修改&#xff09; conda activate fyp运行此代码 conda env export > environment.ymlreq.txt文件 激活…

runtime过程中,常见jar问题解决

io.netty java.lang.NoSuchMethodError: io.netty.buffer.PooledByteBufAllocator.<init>此类问题报错&#xff0c;主要是io.netty 多个jar 冲突导致。、 使用以下命令查看同一个jar 有哪些版本 mvn dependency:resolve -Dclassifiersources对一些不愿意引入的依赖加上…

VIGC:自问自答,高质量视觉指令微调数据获取新思路

从今年四月份开始&#xff0c;随着MiniGPT-4, LLaVA, InstructBLIP等多模态大模型项目的开源&#xff0c;大模型的火从NLP领域烧到了计算机视觉及多模态领域。 多模态大模型需要高质量的图文对话数据进行指令微调&#xff0c;而当前多模态指令微调数据多基于纯文本GPT-4构建&am…

【Purple Pi OH RK3566鸿蒙开发板】OpenHarmony音频播放应用,真实体验感爆棚!

本文转载于Purple Pi OH开发爱好者&#xff0c;作者ITMING 。 原文链接&#xff1a;https://bbs.elecfans.com/jishu_2376383_1_1.html 01注意事项 DevEco Studio 4.0 Beta2&#xff08;Build Version: 4.0.0.400&#xff09; OpenHarmony SDK API 9 创建工程类型选择Appli…

华为云云耀云服务器L实例评测 | 部署H5 一起来吃月饼游戏

文章目录 前言一、云服务器相对传统服务器有什么优势1.1、可伸缩性&#xff08;Scalability&#xff09;1.2、灵活性&#xff08;Flexibility&#xff09;1.3、高可用性&#xff08;High Availability&#xff09;1.4、备份和恢复&#xff08;Backup and Recovery&#xff09;1…

Golang Gorm 创建HOOK

创建的时候&#xff0c;在插入数据之前&#xff0c;想要做一些事情。钩子函数比较简单&#xff0c;就是实现before create的一个方法。 package mainimport ("gorm.io/driver/mysql""gorm.io/gorm" )type Student struct {ID int64Name string gorm:&q…

redis深度历险 千帆竞发 —— 分布式锁

分布式应用进行逻辑处理时经常会遇到并发问题。 比如一个操作要修改用户的状态&#xff0c;修改状态需要先读出用户的状态&#xff0c;在内存里进行修改&#xff0c;改完了再存回去。如果这样的操作同时进行了&#xff0c;就会出现并发问题&#xff0c;因为读取和保存状态这两个…

AUTOSAR-存储基础知识

1、存储基础知识 RAM 又称随机存取存储器&#xff0c;存储单元的内容可以按照需要随机取出或者存入&#xff0c;存取数据比较快。这种存储器在断电时&#xff0c;会丢失其存储内容&#xff0c;所以一般是 CPU运行时会把程序从 ROM 拷贝到 RAM 里面执行。所以一般 RAM 是作为和…

软件测试公式之如何高质量的做BUG分析?

对于BUG分析&#xff0c;测试人员再熟悉不过了。但如果是面对大量的BUG&#xff0c;要如何有效的分析呢&#xff1f;有什么好的方案和行动项&#xff1f;今天聊聊这个话题。 01 BUG分析简单可以分为两类&#xff1a;宏观BUG分析 和 微观BUG分析。 宏观BUG分析&#xff1a;在…

六、线程池的编写与解析 —— TinyWebServer

六、线程池的编写与解析 —— TinyWebServer 一、前言 经过上次数据库连接池的书写&#xff0c;大家也应该明白池的编写。 这里说一下不同点&#xff0c;和一些要注意的点。 为什么使用模板&#xff1f;为什么不用单例模式了&#xff1f;这里的线程池扮演的角色是什么&#x…

【PowerQuery】PowerBI 手动刷新数据内容

PowerBI的手动刷新方式和Excel基本一样&#xff0c;我们通过刷新数据源来实现数据的手动刷新&#xff0c;当然PowerBI 和Excel一样存在着单数据源刷新和全局数据源刷新两个操作。如果希望刷新单个数据源&#xff0c;我们可以在数据字段进行数据的刷新&#xff0c;具体的操作步骤…

阈值回归模型(Threshold Regression Model)及R实现

阈值回归模型是一类回归模型&#xff0c;其中预测变量与结果以阈值依赖的方式相关联。通过引入一个阈值参数&#xff08;也称为转折点&#xff09;&#xff0c;阈值回归模型提供了一种简单而优雅、可解释的方法来建立结果和预测变量之间某些非线性关系的模型。在生物医学领域中…

Pyramid Scene Parsing Network–CVPR,2017论文解读及其pytorch代码

文章目录 Pyramid Scene Parsing Network--CVPR&#xff0c;2017一、背景介绍二、网络结构和优化方法三、实验结果 Pyramid Scene Parsing Network–CVPR&#xff0c;2017 Github代码链接 一、背景介绍 现阶段随着数据集制作精细化、标签种类变多、具有语义相似标签等导致出…

继承的笔记

继承 对象代表什么, 就得封装对应的数据, 并提供数据对应的行为 对于两种不同的类, 但是具有很多共同的属性的时候我们就想着用继承, 我们可以将共同的属性放置在一个类中, 然后, 只需要新建两个类, 继承共有的类, 然后单独写自己的属性特点 继承类 Java 中提供了一个关键字…

Hadoop-Hbase

1. Hbase安装 1.1 安装zookeeper、 hbase 解压至/opt/soft&#xff0c;并分别改名 配置环境变量并source生效 #ZK export ZOOKEEPER_HOME/opt/soft/zk345 export PATH$ZOOKEEPER_HOME/bin:$PATH #HBASE_HOME export HBASE_HOME/opt/soft/hbase235 export PATH$HBASE_HOME/b…