QChart数据可视化

目录

一、QChart基本介绍

1.1 QChart基本概念与用途

1.2 主要类的介绍

1.2.1 QChartView类

1.2.2 QChart类

1.2.3QAbstractSeries类

1.2.4 QAbstractAxis类

1.2.5 QLegendMarker

二、与图表交互

1. 动态绘制数据

2. 深入数据

3. 缩放和滚动

4. 鼠标悬停

三、主题

四、代码实践

4.1 踩坑

4.2 线性图绘制

4.3 散点图

 4.4 柱状图

4.5 饼状图


一、QChart基本介绍

1.1 QChart基本概念与用途

        QtCharts是一个Qt模块,它提供了许多种常见的图表类型,如折线图、柱状图、饼图、散点图、区域图、极坐标图等等。使用QtCharts可以轻松地把数据可视化,帮助用户更好地理解数据,进行分析和决策。以下是Qt官方的介绍:

       The QChart class manages the graphical representation of the chart's series, legends, and axes.

        QChart is a QGraphicsWidget that you can show in a QGraphicsScene. It manages the graphical representation of different types of series and other chart related objects like legend and axes. To simply show a chart in a layout, the convenience class QChartView can be used instead of QChart. In addition, line, spline, area, and scatter series can be presented as polar charts by using the QPolarChart class.

1.2 主要类的介绍

QChart主要由一下几个大类组成:

1.2.1 QChartView类

        视图对象,实际是一个独立的widget,用以展示图表。

1.2.2 QChart类

        是真正的图表对象,QChart需要添加在QChartView对象下才可在正确展示出来。

1.2.3QAbstractSeries类

        是数据集合,在QChart中添加QAbstractSeries,才可以展示出数据,否则QChart只能展现坐标轴 ,主要数据类及继承关系如下。

1.2.4 QAbstractAxis类

        坐标轴类,用来设置QChart类的坐标轴属性,包括范围、精度等,也用来将QAbstractSeries类与QChart类对应起来。

Qt Charts支持以下坐标轴类型:

  • 值轴 QValueAxis):实际值添加到图表的轴上。它是使用QValueAxis类或ValueAxis QML类型实现的。
  • 类别轴(QCategoryAxis):有命名范围和可调范围宽度
  • 条形类别轴 (QBarCategoryAxis):类似于类别轴,但所有范围的范围宽度都相同。bar类别轴是使用QBarCategoryAxis类或BarCategoryAxis QML类型实现的。
  • 日期-时间轴(QDateTimeAxis):将日期和时间添加到图表轴上。它是使用QDateTimeAxis类或DateTimeAxis QML类型实现的。
  • 对数值轴(QLogValueAxis):向图表的轴添加对数刻度。对数标度是一种基于数量级的非线性标度,因此轴上的每个刻度都是前一个刻度乘以一个值。使用QLogValueAxis类或LogValueAxis QML类型实现对数轴

       可以为一个图表定义多个轴。坐标轴可以放在图表的上下左右。此外,轴可以是不同的类型。但是,不支持混合轴类型,这会导致不同的域,例如在同一方向上指定QValueAxis和QLogValueAxis。

1.2.5 QLegendMarker

        图例是一个显示图表图例的图形对象。图例对象不能被创建或删除,但是它们可以通过QChart类被引用。当序列发生变化时,图例状态由QChart或ChartView更新。
        图例可以位于图表的下方或上方,也可以位于图表的左侧或右侧。默认情况下,图例是附加到图表视图的,但它可以分离到一个可以自由移动的单独图形项。可以隐藏图例中的单个标记,也可以隐藏整个图例。
        图例标记可以通过使用QLegendMarker基类和每个序列类型的子类来修改:

        QAreaLegendMarker、QBarLegendMarker、QBoxPlotLegendMarker、                   QCandlestickLegendMarker和QXYLegendMarker。

二、与图表交互

        用户可以通过以下方式与图表进行交互:动态地向图表添加值、深入聚焦数据、放大和缩小图表、滚动图表、单击图表中的项目或将鼠标悬停在图表上。

1. 动态绘制数据

        可以动态地向图表添加数据,并使图表视图自动滚动以显示新数据

2. 深入数据

        例如,可以将下钻效果实现为条形图或饼状图。当用户在图表中选择项目时,将显示该项的更详细视图
        例如,可以对条形图或饼图实现下钻效果。当用户在图表中选择一个项目时,将显示该项目的更详细视图。这是通过删除第一个序列并添加另一个序列来实现的。

3. 缩放和滚动

        用户可以使用键盘进行缩放和滚动。它们可以使用方向键滚动图表,也可以使用正负键放大或缩小图表。此外,QRubberBand可以用来选择要放大的区域。

4. 鼠标悬停

        可以将槽连接到终端用户单击图表中的项或将鼠标悬停在图表上时发出的信号。这使您能够向图表中添加元素,如标注。

三、主题

        主题是应用于图表的所有视觉元素的UI样式相关设置的内置集合,例如颜色、画笔、画刷和字体系列,以及轴、标题和图例。

Qt图表具有以下预定义的主题:

  • Light主题,这是默认主题
  • 天蓝色的主题
  • 黑暗的主题
  • 砂褐色主题
  • 自然颜色系统(NCS)蓝色主题
  • 高反差主题
  • 冰蓝色主题
  • Qt的主题

可以通过更改颜色、画笔、画刷和字体来定制主题。可以通过修改Qt Charts的源代码来添加新的主题

注意:更改主题将覆盖之前应用于该系列的所有自定义。

四、代码实践

4.1 踩坑

必须声明命名空间,库必须与编译器选择模式对应。

using namespace QtCharts;

4.2 线性图绘制

//折线图connect(ui.pushButton_zhexian, &QPushButton::clicked, this, [=] {//QLineSeries *lineSeries1 = new QLineSeries();  //折线//QLineSeries *lineSeries2 = new QLineSeries();QSplineSeries *lineSeries1 = new QSplineSeries(); //平滑曲线QLineSeries *lineSeries2 = new QLineSeries();qsrand(QTime::currentTime().second());for (int i = 0; i <= 41; ++i){	qreal y = qrand() % 100;if (i <= 20){qreal x = i;lineSeries1->append(x, y);}else{qreal x = i - 21;lineSeries2->append(x, y);}}lineSeries1->setColor(Qt::blue);lineSeries1->setPen(QPen(Qt::blue, 2));lineSeries1->setName("line1");//图例的名字lineSeries2->setColor(Qt::red);lineSeries2->setPen(QPen(Qt::red, 2, Qt::PenStyle::DashDotDotLine));lineSeries2->setName("line2");lineSeries1->setPointLabelsVisible(true);lineSeries2->setPointLabelsVisible(true);//创建QChartQChart *chart = new QChart();chart->setTitle("Line Chart");//设置标题chart->addSeries(lineSeries1); //将折线系列添加到图标chart->addSeries(lineSeries2);//修改图例QLegend * legned = chart->legend();legned->setAlignment(Qt::AlignBottom);legned->setBackgroundVisible(false);legned->setMarkerShape(QLegend::MarkerShape::MarkerShapeRectangle);//创建X轴QValueAxis *axisX = new QValueAxis();axisX->setLabelFormat("%.0f");//设置标签格式axisX->setTitleText("X轴");axisX->setRange(0, 20);//设置范围axisX->setTickCount(21); //设置tickCount 即标签数量为21 0-21axisX->setGridLineVisible(false);//设置主刻度线不可见//axisX->hide();//隐藏刻度线 X周 0-10 不可见//创建Y轴QValueAxis *axisY = new QValueAxis();axisY->setTitleText("Y轴");axisY->setRange(0, 100);//设置范围axisY->setTickCount(11); //设置tickCount 即标签数量为11 100进行10等分 11个标签 //关联轴到Chart和QSerieschart->addAxis(axisX, Qt::AlignBottom);chart->addAxis(axisY, Qt::AlignLeft);lineSeries1->attachAxis(axisX);lineSeries1->attachAxis(axisY);lineSeries2->attachAxis(axisX);lineSeries2->attachAxis(axisY);//创建QChartView 对象显示图表QChartView * chartview = new QChartView(chart, ui.tab_3);chartview->setRenderHint(QPainter::Antialiasing);//抗锯齿//显示窗口、QMainWindow *win = new QMainWindow(ui.tab_3);win->setCentralWidget(chartview);win->resize(800, 600);win->setWindowTitle("Test_折线图");win->show();});

 

4.3 散点图

connect(ui.pushButton_sactter, &QPushButton::clicked, this, [=]() {QScatterSeries *scatterSeries = new QScatterSeries();// 添加散点数据qsrand(QTime::currentTime().second());//设置随机数生成器的种子for (int i = 0; i <= 20; i++) {qreal x = i;qreal y = qrand() % 100;scatterSeries->append(x, y);qDebug() << QPoint(x, y);//测试输出}// 创建 QChart 对象QChart *chart = new QChart();chart->setTitle("Scatter Chart"); // 设置标题chart->addSeries(scatterSeries); // 将散点系列添加到图表中// 创建 QValueAxis 对象作为 X 轴QValueAxis *axisX = new QValueAxis();axisX->setLabelFormat("%.0f"); // 设置标签格式axisX->setTitleText("X Axis");axisX->setRange(0, 20); // 设置范围axisX->setTickCount(21); // 设置 tickCount,即标签数量为 21chart->addAxis(axisX, Qt::AlignBottom); // 将 X 轴添加到图表中scatterSeries->attachAxis(axisX); // 散点系列关联 X 轴// 创建 QValueAxis 对象作为 Y 轴QValueAxis *axisY = new QValueAxis();axisY->setTitleText("Y Axis");axisY->setRange(0, 100); // 设置范围axisY->setTickCount(11); // 设置 tickCount,即标签数量为 11chart->addAxis(axisY, Qt::AlignLeft); // 将 Y 轴添加到图表中scatterSeries->attachAxis(axisY); // 散点系列关联 Y 轴// 创建 QChartView 对象显示图表QChartView *chartView = new QChartView(chart);chartView->setRenderHint(QPainter::Antialiasing); // 抗锯齿QMainWindow *win = new QMainWindow(ui.tab_3);win->setCentralWidget(chartView);win->resize(800, 600);win->setWindowTitle("Test_饼状图");win->show();});

 4.4 柱状图

connect(ui.pushButton_bar, &QPushButton::clicked, this, [=]() {//创建柱状形集对象QBarSet* set1 = new QBarSet("语文");QBarSet* set2 = new QBarSet("数学");QBarSet* set3 = new QBarSet("英语");*set1 << 130 << 120 << 110 << 97 << 88;set2->append({ 148,128,137,98,88 }); set3->append(123);set3->append(86);set3->append(98);set3->append(68);set3->append(99);set1->setLabelColor(Qt::red);set2->setLabelColor(Qt::green);set3->setLabelColor(Qt::blue);//QBarSet封装为QStackedBarSeries //QBarSet类型封装成QStackedBarSeries类型,是因为chart->append不能接收QBarSet的类型。QStackedBarSeries *bar1 = new QStackedBarSeries();bar1->append(set1);QStackedBarSeries *bar2 = new QStackedBarSeries();bar2->append(set2);QStackedBarSeries *bar3 = new QStackedBarSeries();bar3->append(set3);//QChartQChart* chart = new QChart();chart->addSeries(bar1);chart->addSeries(bar2);chart->addSeries(bar3);//创建QChartView 对象显示图表QChartView * chartview = new QChartView(chart, ui.tab_3);//创建X轴QBarCategoryAxis *axisX = new QBarCategoryAxis();QStringList list = { "小张","王五","晓明" ,"小红" ,"小绿" };axisX->append(list);axisX->setTitleText("姓名");axisX->setGridLineVisible(false);//创建Y轴QValueAxis *axisY = new QValueAxis();axisY->setTitleText("成绩");axisY->setRange(0, 150);//设置范围axisY->setTickCount(6); //设置tickCount 即标签数量为6 150进行5等分 6个标签 //设定坐标轴与数据对应chart->setAxisX(axisX, bar1);chart->setAxisX(axisX, bar2);chart->setAxisX(axisX, bar3);chart->setAxisY(axisY, bar1);chart->setAxisY(axisY, bar2);chart->setAxisY(axisY, bar3);//显示窗口、QMainWindow *win = new QMainWindow(ui.tab_3);win->setCentralWidget(chartview);win->resize(800, 600);win->setWindowTitle("Test_柱状图");win->show();});

4.5 饼状图

        该代码中实践饼状图的基本绘制方法和图形属性的设置,设置opengl加速绘制以及chartview的grap抓取保存图片的方法对比QScreen的截屏效果。

connect(ui.pushButton_bingzhuang, &QPushButton::clicked, this, [=]() {QChartView*view = new QChartView(ui.tab_3);view->setRenderHint(QPainter::Antialiasing);QChart* chart = new QChart();chart->setTitle("成绩分布");view->setChart(chart);//设置饼图QPieSeries*pie = new QPieSeries;QPieSlice* s1 = pie->append("60分以下",20);QPieSlice* s2 = pie->append("60-80分", 30);QPieSlice* s3 = pie->append("60-90分", 30);QPieSlice* s4 = pie->append("90-100分", 20);s4->setExploded(true);//设置此分块突出pie->setHoleSize(0.4);// 设置饼状图中间洞大小 0.0-1.0之间pie->setLabelsPosition(QPieSlice::LabelOutside);//设置slice label的位置pie->setLabelsVisible(true);pie->setUseOpenGL(true);//使用OpenGl来画 GPU 并行不卡顿 QAbstractSeries方法//字体QFont font = qApp->font();font.setBold(true);font.setPointSize(20);chart->setTitleFont(font);//图例chart->legend()->setAlignment(Qt::AlignLeft);//设置各个模块颜色s1->setColor(Qt::red);s2->setColor(Qt::blue);s3->setColor(Qt::green);s4->setColor(Qt::yellow);chart->addSeries(pie);//设置主题 默认lightchart->setTheme(QChart::ChartTheme::ChartThemeBlueCerulean);//显示窗口、QMainWindow *win = new QMainWindow(ui.tab_3);win->setCentralWidget(view);win->resize(800, 600);win->setWindowTitle("Test_饼状图");win->show();//保存图片 ChartView 自有方式QPixmap p = view->grab();//QImage image = p.toImage();image.save("chart.png");//截屏 通过winIDQScreen *screen=QGuiApplication::primaryScreen();//保留应用程序的主屏幕(最初显示QWindows的屏幕)QPixmap pic = screen->grabWindow(view->winId());QImage image2 = pic.toImage();image2.save("chartPie.png");});

 

五、在实际项目中的应用 

        QCharts在实际的项目中可以很好的可视化数据,以多种形式统计可视化程序每日产生的数据,从而多维度的评估项目的运行状况和运维效果等。

       如在交通的停车场场景中对于不同时间尺度可以使用折线图统计车流量(对于商场等常有活动的车场运维更有意义),通过饼状图统计不同支付方式的占比(对于企事业单位学校等固定卡、储值卡、临时卡、ETC等统计更有意义)、通过统计车厂外围不同设备的异常更好的评估运行的稳定性、通过统计每日相机的识别平均置信度评估相机等架设合理性等等。

        业务的评估对于不同场景下的运营状况有直观的反馈,设备 异常、识别率、不同级别的错误报告、内存使用等等的统计对于无人车厂运行的稳定应也有直观的反馈。

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

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

相关文章

Chrome和edge浏览器如何为任何网站强制暗模式

前言 因为我的编辑器是黑色&#xff0c;可能是看的时间长了比较喜欢这种颜色了&#xff0c;感觉白色有些刺眼。尤其是看文章时&#xff0c;两边的空白纯白色&#xff0c;所以强迫症搜素设置了谷歌浏览器和edge如何设置成黑色。 Chrome和edge浏览器如何为任何网站强制暗模式 前…

使用 Elastic 收集 Windows 遥测数据:ETW Filebeat 输入简介

作者&#xff1a;来自 Elastic Chema Martinez 在安全领域&#xff0c;能够使用 Windows 主机的系统遥测数据为监控、故障排除和保护 IT 环境开辟了新的可能性。意识到这一点&#xff0c;Elastic 推出了专注于 Windows 事件跟踪 (ETW) 的新功能 - 这是一种强大的 Windows 原生机…

k8s网络服务

k8s 中向外界提供服务的几种方法port-forward、NodePort&#xff0c;以及 更加常用的提供服务的资源ingress。 1 kubectl port-forward service/redis 6379:6379 现在k8s中有一个pod运行在6379&#xff0c;本机访问映射到6379上&#xff0c;它可以针对部署&#xff0c;服务&…

手动设置 IP 地址和使用 DHCP 在以下方面存在区别

手动设置 IP 地址和使用 DHCP 在以下方面存在区别&#xff1a; 配置过程 手动设置 IP 地址&#xff1a;需要用户手动输入 IP 地址、子网掩码、默认网关、DNS 服务器地址等网络配置参数。在 Windows 系统中&#xff0c;通常要打开 “控制面板”&#xff0c;进入 “网络和共享中…

Python网络爬虫基础

Python网络爬虫是一种自动化工具&#xff0c;用于从互联网上抓取信息。它通过模拟人类浏览网页的行为&#xff0c;自动地访问网站并提取所需的数据。网络爬虫在数据挖掘、搜索引擎优化、市场研究等多个领域都有广泛的应用。以下是Python网络爬虫的一些基本概念&#xff1a; 1.…

实现跨语言通信:Rust 和 Thrift 的最佳实践

前言 在分布式系统中&#xff0c;服务之间高效且安全的通信至关重要。Apache Thrift 是一个被广泛应用的跨语言 RPC&#xff08;远程过程调用&#xff09;框架&#xff0c;它支持多种编程语言&#xff0c;包括 Rust。Rust 以其卓越的性能和内存安全保障&#xff0c;成为越来越…

微信小程序按字母顺序渲染城市 功能实现详细讲解

在微信小程序功能搭建中&#xff0c;按字母渲染城市会用到多个ES6的方法&#xff0c;如reduce&#xff0c;map&#xff0c;Object.entries()&#xff0c;Object.keys() &#xff0c;需要组合熟练掌握&#xff0c;才能优雅的处理数据完成渲染。 目录 一、数据分析 二、数据处理 …

框架学习07 - SpringMVC 其他功能实现

一. 拦截器实现HandlerInterceptor 接⼝ SpringMVC 中的 Interceptor 拦截器也是相当重要和相当有⽤的&#xff0c;它的主要作⽤是拦截⽤户的请求并进⾏相应的处理。⽐如通过它来进⾏权限验证&#xff0c;或者是来判断⽤户是否登陆等操作。对于 SpringMVC 拦截器的定义⽅式有两…

前端JavaScript(一)---基本介绍

Javascript是一种由Netscape(网景)的LiveScript发展而来的原型化继承的面向对象的动态类型的区分大小写的客户端脚本语言&#xff0c;主要目的是为了解决服务器端语言&#xff0c;比如Perl&#xff0c;遗留的速度问题&#xff0c;为客户提供更流畅的浏览效果。当时服务端需要对…

git的使用(简洁版)

什么是 Git&#xff1f; Git 是一个分布式版本控制系统 (DVCS)&#xff0c;用于跟踪文件的更改并协调多人之间的工作。它由 Linus Torvalds 在 2005 年创建&#xff0c;最初是为了管理 Linux 内核的开发。Git 的主要目标是提供高效、易用的版本控制工具&#xff0c;使得开发者…

设计模式之破环单例模式和阻止破坏

目录 1. 序列化和反序列化2. 反射 这里单例模式就不多说了 23种设计模式之单例模式 1. 序列化和反序列化 这里用饿汉式来做例子 LazySingleton import java.io.Serializable;public class LazySingleton implements Serializable {private static LazySingleton lazySinglet…

kotlin 的循环

循环的步长可以通过step关键字进行设置 在Kotlin中&#xff0c;循环的默认步长为1。如果需要改变步长&#xff0c;可以在循环表达式中使用step关键字。例如&#xff0c;要从0循环到100&#xff0c;步长为2&#xff0c;可以这样写&#xff1a; for (i in 0..100 step 2) {prin…

vscode可以编译通过c++项目,但头文件有红色波浪线的问题

1、打开 VSCode 的设置&#xff0c;可以通过快捷键 Ctrl Shift P 打开命令面板&#xff0c;然后搜索并选择 “C/C: Edit Configurations (JSON)” 命令&#xff0c;这将在 .vscode 文件夹中创建或修改 c_cpp_properties.json 文件 {"configurations": [{"name…

Java与Kotlin在鸿蒙中的地位

在当今移动操作系统领域&#xff0c;华为推出的鸿蒙系统&#xff08;HarmonyOS&#xff09;正逐渐崭露头角&#xff0c;成为与Android、iOS并驾齐驱的操作系统之一。对于开发者而言&#xff0c;了解如何为鸿蒙系统开发高质量的应用程序变得至关重要。在这篇文章中&#xff0c;我…

VS Code前端常用插件

通用类 auto close tag auto rename tag beautify class autocomplete for html Code Runner css peek dash JavaScript Debugger document this eslint font-awesome codes for html filesize git history gitlens html css support HTMLHint htmltagwrap indenticator Intel…

Android 16 开发者预览版抢先使用

Android 16 开发者预览版 获取 Android 16在 Google Pixel 设备上获取 Android 16设置 Android 模拟器 设置 Android 16 SDK获取 Android Studio安装 SDK更新应用的 build 配置 获取 Android 16 你可以通过以下任一方式获取 Android 16 在 Google Pixel 设备上获取 Android 1…

从web前端角度浅析网络安全

摘 要 当前网络与信息技术已经有了非常大的进步﹐Web前端技术的使用、和其安全问题也越来越受到我们的重视。 Web前端技术毫无疑问是网络技术的入口&#xff0c;是我们互联网的门户&#xff0c;也是网络安全中最容易被攻击的环节&#xff0c;经常受到黑客的青睐。因此&…

解析生成对抗网络(GAN):原理与应用

目录 一、引言 二、生成对抗网络原理 &#xff08;一&#xff09;基本架构 &#xff08;二&#xff09;训练过程 三、生成对抗网络的应用 &#xff08;一&#xff09;图像生成 无条件图像生成&#xff1a; &#xff08;二&#xff09;数据增强 &#xff08;三&#xff…

Vue.js 开发技巧:懒加载组件 vs 直接导入,何时选择哪个?

在开发 Vue.js 应用时&#xff0c;决定是否使用 动态加载组件&#xff08;懒加载&#xff09;或者 直接导入并注册组件&#xff0c;是前端开发中一个重要的设计决策。两者各有优势&#xff0c;选择合适的方式可以提升应用的性能、可维护性和开发效率。那么&#xff0c;究竟什么…

【大模型】从零样本到少样本学习:一文读懂 Zero-shot、One-shot 和 Few-shot 的核心原理与应用!

《从零样本到少样本学习&#xff1a;一文读懂 Zero-shot、One-shot 和 Few-shot 的核心原理与应用&#xff01;》 正文&#xff1a; 在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;Zero-shot、One-shot 和 Few-shot 学习已经成为衡量大语言模型泛化能力的重要指标…