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

news2025/5/17 14:49:02

文章目录

    • 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 sys
    
    from 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 QPointF
    
    class MainWindow(QMainWindow):  # 定义MainWindow类,继承自QMainWindow
        def __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  # 初始化图表视图为None
            self.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)  # 设置主窗口的中心部件为图表视图
    
        @profile
        def 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
    
        @profile
        def 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
    
        @profile
        def 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 sys
    
    from 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 QPointF
    
    class MainWindow(QMainWindow):  # 定义MainWindow类,继承自QMainWindow
        def __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  # 初始化图表视图为None
            self.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到100
            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)  # 设置主窗口的中心部件为图表视图
    
        @profile
        def 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)  # 将新的点添加到折线序列中
    
    
        @profile
        def 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)  # 将新的点添加到折线序列中
    
    
        @profile
        def 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倍;
  • 测试代码:

        @profile
        def 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)  # 替换折线序列中的点
        @profile
        def 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.coloradmin.cn/o/2377750.html

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

相关文章

如何在 Windows 10 或 11 上使用命令提示符安装 PHP

我们可以在 Windows 上从其官方网站下载并安装 PHP 的可执行文件,但使用命令提示符或 PowerShell 更方便。 PHP 并不是一种新的或不为人知的脚本语言,它已经存在并被全球数千名网络开发人员使用。它以开源许可并分发,广泛用于 LAMP 堆栈中。然而,与 Linux 相比,它在 Wind…

RK3588 ADB使用

安卓adb操作介绍 adb(Android Debug Bridge)是一个用于与安卓设备进行通信和控制的工具。adb可以通过USB或无线网络连接安卓设备,执行各种命令,如安装和卸载应用,传输文件,查看日志,运行shell命…

Please install it with pip install onnxruntime

无论怎么安装都是 Please install it with pip install onnxruntime 我python 版本是3.11 ,我换成3.10 解决了

低损耗高效能100G O Band DWDM 10km光模块 | 支持密集波分复用

目录 前言 一、产品概述 100G QSFP28 O Band DWDM 10km光模块核心特点包括: 二、为何选择O Band DWDM方案? 1.低色散损耗,传输更稳定 2.兼容性强 三、典型应用场景 1.数据中心互联(DCI) 2.企业园区/智慧城市组网 3.电信…

第二十六天打卡

全局变量 global_var 全局变量是定义在函数、类或者代码块外部的变量,它在整个程序文件内都能被访问。在代码里, global_var 就是一个全局变量,下面是相关代码片段: print("\n--- 变量作用域示例 ---") global_var …

阿里云ECS部署Dify

一:在ECS上面安装Docker 关防火墙 sudo systemctl stop firewalld 检查防火墙状态 systemctl status firewalld sudo yum install -y yum-utils device-mapper-persistent-data lvm2 设置阿里镜像源,安装并启动docker [base] nameCentOS-$releas…

日志与策略模式

什么是设计模式 IT⾏业 ,为了让 菜鸡们不太拖⼤佬的后腿, 于是⼤佬们针对⼀些经典的常⻅的场景, 给定了⼀些对应的解决⽅案, 这个就是 设计模式 日志认识 计算机中的⽇志是记录系统和软件运⾏中发⽣事件的⽂件,主要作⽤是监控运⾏状态、记录异常信 息&#xff…

Jenkins 最佳实践

1. 在Jenkins中避免调度过载 过载Jenkins以同时运行多个作业可能导致资源竞争、构建速度变慢和系统性能问题。分配作业启动时间可以防止瓶颈,并确保更顺畅的执行。如何实现? 在Cron表达式中使用H:引入抖动(jitter)&a…

天能股份SAP系统整合实战:如何用8个月实现零业务中断的集团化管理升级

目录 天能股份SAP系统整合案例:技术驱动集团化管理的破局之路 一、企业背景:新能源巨头的数字化挑战 二、项目难点:制造业的特殊攻坚战 1. 生产连续性刚性需求 2. 数据整合三重障碍 3. 资源限制下的技术突围 三、解决方案:S…

uniapp-商城-59-后台 新增商品(属性的选中,进行过滤展示,filter,some,every和map)

前面讲了属性的添加,添加完成后,数据库中已经存在数据了,这时再继续商品的添加时,就可以进行属性的选择了。 在商品添加过程中,属性选择是一个关键步骤。首先,界面需要展示嵌套的属性数据,用户通…

B2C 商城转型指南:传统企业如何用 ZKmall模板商城实现电商化

在数字化浪潮席卷全球的当下,传统企业向电商转型已不再是选择题,而是关乎生存与发展的必答题。然而,缺乏技术积累、开发成本高、运营经验不足等问题,成为传统企业转型路上的 “拦路虎”。ZKmall模板商城以其低门槛、高灵活、强适配…

生成树协议 - STP

目录 BPDU STP选举机制 STP端口状态 STP计时器 STP拓扑变更机制 生成树协议(Spanning Tree Protocol),简写为STP。 STP是二层网络中用于消除环路的协议,通过阻塞冗余链路,使可用链路在拓扑上呈现出无环的树结构&…

计算机指令分类和具体的表示的方式

1.关于计算机的指令系统 下面的这个就是我们的一个简单的计算机里面涉及到的指令: m就是我们的存储器里面的地址,可以理解为memory这个意思,r可以理解为rom这样的单词的首字母,帮助我们去进行这个相关的指令的记忆,不…

mvc-service引入

什么是业务层 1)Model1(JSP)和Model2(模糊的mvc): MVC:Model(模型),View(视图),Controller(控制器) 视图层:用于数据展示以及用户交互的界…

基于微信小程序的城市特色旅游推荐应用的设计与实现

💗博主介绍💗:✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示:文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…

【暗光图像增强】【基于CNN的方法】2020-AAAI-EEMEFN

EEMEFN:Low-Light Image Enhancement via Edge-Enhanced Multi-Exposure Fusion Network EEMEFN:基于边缘增强多重曝光融合网络的低光照图像增强 AAAI 2020 论文链接 0.论文摘要 本研究专注于极低光照条件下的图像增强技术,旨在提升图像亮度…

【Linux】ssh命令 – 安全的远程连接服务

原创:厦门微思网络 SSH命令的概念 ssh命令的功能是安全地远程连接服务器主机系统,作为OpenSSH套件中的客户端连接工具,ssh命令可以让我们轻松地基于SSH加密协议进行远程主机访问,从而实现对远程服务器的管理工‍作。 语法 ssh 参…

AT9850B—单北斗导航定位芯片

AT9850B是一款高性能低功耗双频单北斗卫星导航接收机SOC单芯片。芯片集成射频前端和数字基带、多模式卫星信号处理引擎、电源管理功能,集成度高,外围应用电路简洁。 支持中国北斗B1I/B1C单频定位或B1I/B1C/B2a双频定位,支持北斗二号和三号&a…

工业4G路由器IR5000公交站台物联网应用解决方案

随着城市化进程的加速,公共交通是智慧城市的重要枢纽。城市公共交通由无数的公交站台作作为节点组合而成,其智能化升级成为提升城市出行效率与服务质量的关键。传统公交站台信息发布滞后、缺乏实时性,难以满足乘客对公交信息快速获取的需求&a…

idea中Lombok失效的解决方案

Lombok 是一个 Java 库,旨在通过注解简化 Java 代码的编写,减少样板代码,提高开发效率。它通过自动生成常见的代码(如 getter、setter、构造函数等)来减少开发者的手动编码工作。 一般Lombok失效有四步排查方案&#…