当前位置: 首页 > news >正文

Qt图表绘制(QtCharts)- 性能优化(13)

文章目录

    • 1 批量替换代替追加
      • 1.1 测试1
      • 1.2 测试2
      • 1.3 测试3
    • 2 开启OpenGL
      • 2.1 测试1
      • 2.2 测试2
      • 2.3 测试3
      • 2.4 测试4


更多精彩内容
👉内容导航 👈
👉Qt开发 👈
👉QtCharts绘图 👈
👉python开发 👈

1 批量替换代替追加

环境说明
系统windows10
python3.13
pyside66.8.3
性能分析工具line_profiler_pycharm
  • 如下所示,使用replace添加数据和使用append添加数据性能对比,单次添加数据越多,replace性能比append越强

  • 示例代码

    import random  # 导入random模块,用于生成随机数
    import sysfrom PySide6.QtCharts import QChart, QChartView, QLineSeries, QValueAxis  # 导入QtCharts模块,用于创建图表和轴
    from PySide6.QtCore import QTimer  # 导入QTimer,用于定时更新图表
    from PySide6.QtCore import Qt  # 导入Qt核心模块,用于设置对齐方式等
    from PySide6.QtGui import QPainter  # 导入QPainter,用于设置图表的渲染提示
    from PySide6.QtWidgets import QApplication, QMainWindow  # 导入PySide6的QApplication和QMainWindow类
    from line_profiler_pycharm import profile
    from PySide6.QtCore import QPointFclass MainWindow(QMainWindow):  # 定义MainWindow类,继承自QMainWindowdef __init__(self):super().__init__()  # 调用父类的构造函数self.setWindowTitle("PySide6 折线图示例")  # 设置窗口标题self.setGeometry(100, 100, 800, 600)  # 设置窗口的位置和大小self.timer = QTimer()  # 创建一个定时器self.timer.timeout.connect(self.update_chart)  # 连接定时器超时信号到update_chart方法self.timer.start(10)  # 设置定时器间隔为10毫秒,并启动定时器# print(help(QChart))  # 这行代码可以用于打印QChart类的帮助信息,目前被注释掉了self.chart_view = None  # 初始化图表视图为Noneself.series1 = QLineSeries()  # 创建一个折线序列对象self.series2 = QLineSeries()  # 创建一个折线序列对象# self.series1.setUseOpenGL(True)  # 设置折线序列使用OpenGL渲染# self.series2.setUseOpenGL(True)  # 设置折线序列使用OpenGL渲染self.init_chart()  # 调用初始化图表的方法def init_chart(self):  # 定义初始化图表的方法# 设置名称self.series1.setName("series1")  # 设置折线的名称self.series2.setName("series2")  # 设置折线的名称# 创建图表chart = QChart()  # 创建一个图表对象chart.addSeries(self.series1)  # 将折线序列添加到图表中chart.addSeries(self.series2)  # 将折线序列添加到图表中chart.setTitle("简单的折线图")  # 设置图表的标题# chart.setAnimationOptions(QChart.AnimationOption.SeriesAnimations)  # 设置图表不使用动画# 创建x轴和y轴axis_x = QValueAxis()  # 创建一个数值型x轴axis_y = QValueAxis()  # 创建一个数值型y轴chart.addAxis(axis_x, Qt.AlignmentFlag.AlignBottom)  # 将x轴添加到图表底部chart.addAxis(axis_y, Qt.AlignmentFlag.AlignLeft)  # 将y轴添加到图表左侧self.series1.attachAxis(axis_x)  # 将折线序列附着到x轴self.series1.attachAxis(axis_y)  # 将折线序列附着到y轴self.series2.attachAxis(axis_x)  # 将折线序列附着到x轴self.series2.attachAxis(axis_y)  # 将折线序列附着到y轴# 创建图表视图self.chart_view = QChartView(chart)  # 创建一个图表视图对象,并将图表添加进去self.chart_view.setRenderHint(QPainter.RenderHint.Antialiasing)  # 设置图表视图的渲染提示为抗锯齿# 设置主窗口的中心部件self.setCentralWidget(self.chart_view)  # 设置主窗口的中心部件为图表视图@profiledef update_chart1(self):  # 定义更新图表的方法"""使用append方法更新折线序列:return: """for i in range(10):  # 循环10次random_integer = random.randint(1, 100)  # 生成一个1到100之间的随机整数self.series1.append(self.series1.count(), random_integer)  # 将新的点添加到折线序列中chart = self.chart_view.chart()  # 获取图表视图中的图表对象axis_x = chart.axes(Qt.Orientation.Horizontal)[0]  # 获取图表中的x轴对象axis_y = chart.axes(Qt.Orientation.Vertical)[0]  # 获取图表中的y轴对象axis_x.setRange(0, self.series1.count())  # 设置x轴的范围,使其从0到当前折线序列点的数量axis_y.setRange(0, 100)  # 设置y轴的范围,使其从0到100@profiledef update_chart2(self):  """使用replace方法更新折线序列:return: """data = self.series2.points()for i in range(10):  # 循环10次random_integer = random.randint(1, 100)  # 生成一个1到100之间的随机整数data.append(QPointF(len(data), random_integer))  # 将新的点添加到折线序列中self.series2.replace(data)  # 替换折线序列中的点chart = self.chart_view.chart()  # 获取图表视图中的图表对象axis_x = chart.axes(Qt.Orientation.Horizontal)[0]  # 获取图表中的x轴对象axis_y = chart.axes(Qt.Orientation.Vertical)[0]  # 获取图表中的y轴对象axis_x.setRange(0, self.series2.count())  # 设置x轴的范围,使其从0到当前折线序列点的数量axis_y.setRange(0, 100)  # 设置y轴的范围,使其从0到100@profiledef update_chart(self):  # 定义更新图表的方法self.update_chart1()  # 调用更新图表的方法self.update_chart2()  # 调用更新图表的方法if __name__ == "__main__":  # 确保只有在直接运行此脚本时才会执行下面的代码app = QApplication(sys.argv)  # 创建一个QApplication对象window = MainWindow()  # 创建一个MainWindow对象window.show()  # 显示主窗口sys.exit(app.exec())  # 进入应用程序的主循环,并等待退出

1.1 测试1

  • 测试方法:定时器1秒刷新1次,每次在循环中添加10个点数据;
  • 测试结果:
    • 从整个函数看update_chart1耗时是update_chart2的6.5倍;
    • 从单行代码看append耗时是replace的11.3倍;

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

1.2 测试2

  • 测试方法:定时器1秒刷新1次,每次在循环中添加1000个点数据;
  • 测试结果:
    • 从整个函数看update_chart1耗时是update_chart2的199倍;
    • 从单行代码看append耗时是replace的750倍;

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

1.3 测试3

  • 测试方法:定时器10毫秒刷新1次,每次在循环中添加10个点数据;
  • 测试结果:
    • 从整个函数看update_chart1耗时是update_chart2的5.57倍;
    • 从单行代码看append耗时是replace的8.82倍;

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2 开启OpenGL

环境说明
系统windows10
python3.13
pyside66.8.3
性能分析工具line_profiler_pycharm
  • 如下所示,对比开启OpenGL和开启OpenGL的性能区别;当使用appeng添加数据时,开启opengl和不开opengl的区别最大;

  • 示例代码:

    import random  # 导入random模块,用于生成随机数
    import sysfrom PySide6.QtCharts import QChart, QChartView, QLineSeries, QValueAxis  # 导入QtCharts模块,用于创建图表和轴
    from PySide6.QtCore import QTimer  # 导入QTimer,用于定时更新图表
    from PySide6.QtCore import Qt  # 导入Qt核心模块,用于设置对齐方式等
    from PySide6.QtGui import QPainter  # 导入QPainter,用于设置图表的渲染提示
    from PySide6.QtWidgets import QApplication, QMainWindow  # 导入PySide6的QApplication和QMainWindow类
    from line_profiler_pycharm import profile
    from PySide6.QtCore import QPointFclass MainWindow(QMainWindow):  # 定义MainWindow类,继承自QMainWindowdef __init__(self):super().__init__()  # 调用父类的构造函数self.setWindowTitle("PySide6 折线图示例")  # 设置窗口标题self.setGeometry(100, 100, 800, 600)  # 设置窗口的位置和大小self.timer = QTimer()  # 创建一个定时器self.timer.timeout.connect(self.update_chart)  # 连接定时器超时信号到update_chart方法self.timer.start(1000)  # 设置定时器间隔为10毫秒,并启动定时器self.chart_view = None  # 初始化图表视图为Noneself.series1 = QLineSeries()  # 创建一个折线序列对象self.series2 = QLineSeries()  # 创建一个折线序列对象self.series1.setUseOpenGL(True)  # 设置折线序列使用OpenGL渲染# self.series2.setUseOpenGL(True)  # 设置折线序列使用OpenGL渲染self.init_chart()  # 调用初始化图表的方法def init_chart(self):  # 定义初始化图表的方法# 设置名称self.series1.setName("series1")  # 设置折线的名称self.series2.setName("series2")  # 设置折线的名称# 创建图表chart = QChart()  # 创建一个图表对象chart.addSeries(self.series1)  # 将折线序列添加到图表中chart.addSeries(self.series2)  # 将折线序列添加到图表中chart.setTitle("简单的折线图")  # 设置图表的标题# chart.setAnimationOptions(QChart.AnimationOption.SeriesAnimations)  # 设置图表不使用动画# 创建x轴和y轴axis_x = QValueAxis()  # 创建一个数值型x轴axis_y = QValueAxis()  # 创建一个数值型y轴axis_y.setRange(0, 100)  # 设置y轴的范围,使其从0到100chart.addAxis(axis_x, Qt.AlignmentFlag.AlignBottom)  # 将x轴添加到图表底部chart.addAxis(axis_y, Qt.AlignmentFlag.AlignLeft)  # 将y轴添加到图表左侧self.series1.attachAxis(axis_x)  # 将折线序列附着到x轴self.series1.attachAxis(axis_y)  # 将折线序列附着到y轴self.series2.attachAxis(axis_x)  # 将折线序列附着到x轴self.series2.attachAxis(axis_y)  # 将折线序列附着到y轴# 创建图表视图self.chart_view = QChartView(chart)  # 创建一个图表视图对象,并将图表添加进去self.chart_view.setRenderHint(QPainter.RenderHint.Antialiasing)  # 设置图表视图的渲染提示为抗锯齿# 设置主窗口的中心部件self.setCentralWidget(self.chart_view)  # 设置主窗口的中心部件为图表视图@profiledef update_chart1(self):  # 定义更新图表的方法"""开启OpenGL渲染,使用append方法更新折线序列:return:"""for i in range(10):  # 循环10次random_integer = random.randint(1, 100)  # 生成一个1到100之间的随机整数self.series1.append(self.series1.count(), random_integer)  # 将新的点添加到折线序列中@profiledef update_chart2(self):"""不开启OpenGL渲染,使用append方法更新折线序列:return:"""for i in range(10):  # 循环10次random_integer = random.randint(1, 100)  # 生成一个1到100之间的随机整数self.series2.append(self.series2.count(), random_integer)  # 将新的点添加到折线序列中@profiledef update_chart(self):  # 定义更新图表的方法self.update_chart1()  # 调用更新图表的方法self.update_chart2()  # 调用更新图表的方法chart = self.chart_view.chart()  # 获取图表视图中的图表对象axis_x = chart.axes(Qt.Orientation.Horizontal)[0]  # 获取图表中的x轴对象max_x = self.series2.count()axis_x.setRange(0, max_x)  # 设置x轴的范围,使其从0到当前折线序列点的数量if __name__ == "__main__":  # 确保只有在直接运行此脚本时才会执行下面的代码app = QApplication(sys.argv)  # 创建一个QApplication对象window = MainWindow()  # 创建一个MainWindow对象window.show()  # 显示主窗口sys.exit(app.exec())  # 进入应用程序的主循环,并等待退出

2.1 测试1

  • 测试方法:定时器1秒刷新1次,每次在循环中添加10个点数据;
  • 测试结果:
    • 从整个函数看update_chart2耗时是update_chart1的9.7倍;
    • 从单行代码看append添加数据不开启opengl耗时是开启opengl的21.3倍;

在这里插入图片描述

2.2 测试2

  • 测试方法:定时器1秒刷新1次,每次在循环中添加1000个点数据;
  • 测试结果:
    • 从整个函数看update_chart2耗时是update_chart1的123倍;
    • 从单行代码看append添加数据不开启opengl耗时是开启opengl的169倍;

在这里插入图片描述

2.3 测试3

  • 测试方法:定时器10毫秒刷新1次,每次在循环中添加10个点数据;
  • 测试结果:
    • 从整个函数看update_chart2耗时是update_chart1的72.5倍;
    • 从单行代码看append添加数据不开启opengl耗时是开启opengl的113倍;

在这里插入图片描述

2.4 测试4

  • 测试方法:将使用append添加数据改为使用replace添加数据,定时器10毫秒刷新1次,每次在循环中添加10个点数据;

  • 测试结果:

    • 从整个函数看update_chart2耗时是update_chart1的1.84倍;
    • 从单行代码看replace添加数据不开启opengl耗时是开启opengl的11倍;
  • 测试代码:

        @profiledef update_chart1(self):  # 定义更新图表的方法"""开启OpenGL渲染,使用append方法更新折线序列:return:"""data = self.series1.points()for i in range(10):  # 循环10次random_integer = random.randint(1, 100)  # 生成一个1到100之间的随机整数data.append(QPointF(len(data), random_integer))  # 将新的点添加到折线序列中self.series1.replace(data)  # 替换折线序列中的点@profiledef update_chart2(self):"""不开启OpenGL渲染,使用append方法更新折线序列:return:"""data = self.series2.points()for i in range(10):  # 循环10次random_integer = random.randint(1, 100)  # 生成一个1到100之间的随机整数data.append(QPointF(len(data), random_integer))  # 将新的点添加到折线序列中self.series2.replace(data)  # 替换折线序列中的点
    

在这里插入图片描述



http://www.xdnf.cn/news/478207.html

相关文章:

  • 关于Redisson分布式锁的用法
  • TRTC实时对话式AI解决方案,助力人机语音交互极致体验
  • Python 编程技巧 @ 玩转 For 循环
  • Linux `ps` 命令深度解析与高阶应用指南
  • 简单介绍C++中线性代数运算库Eigen
  • 【未完】【GNN笔记】EvolveGCN:Evolving Graph Convolutional Networks for Dynamics Graphs
  • sqli-labs靶场29-31关(http参数污染)
  • ECPF 简介
  • python爬虫实战训练
  • vscode debug node + 前端
  • 学习51单片机02
  • Vue.js---计算属性computed和lazy
  • 简单图像自适应亮度对比度调整
  • 【Python-Day 14】玩转Python字典(上篇):从零开始学习创建、访问与操作
  • Flutter目录结构介绍、入口、Widget、Center组件、Text组件、MaterialApp组件、Scaffold组件
  • 【RK3588嵌入式图形编程】-Cairo-绘图基础-线条
  • Armijo rule
  • 从另一个视角理解TCP握手、挥手与可靠传输
  • k8s灰度发布
  • MES系统与ERP、SCM、QMS、APS系统的关系
  • 蓝牙网关都有哪些型号?
  • 【笔记】记一次PyCharm的问题反馈
  • PyTorch 的 F.scaled_dot_product_attention 返回Nan
  • 微服务初步学习
  • 变量赋值和数据类型
  • Git 笔记
  • 将已打包好的aar文件,上传到 Coding 的 Maven 仓库
  • uniapp实现在线pdf预览以及下载
  • node.js文件系统(fs) - 创建文件、打开文件、写入数据、追加数据、读取数据、创建目录、删除目录
  • 鸿蒙NEXT开发动画案例10