提到 GUI 绘图,大家可能第一反应是 OpenGL 和 Matplotlib,但其实基于 Qt 平台还有个功能强大的 pyqtgraph 绘图库,不仅支持丰富的图形种类,还能实时更新绘图数据并进行交互式操作。

不同于网上其他文章或代码讲解,今天我们集中只关注实时绘制数据功能的实现。为了更精准学习该 pyqtgraph 模块功能,我们将参考官方给出的实例来边学边练。

1. pyqtgraph 简介

1.1 pyqtgraph 特点

关于 pyqtgraph 与 Matplotlib 的对比,大致要点如下:

  1. pyqtgraph 在画图方面不如 Matplotlib 功能完整和成熟,但运行更快
  2. Matplotlib 旨在绘制高质量图像,pyqtgraph 则主要面向数据抓取和数据分析的应用
  3. 相比 Matplotlib,pyqtgraph 对 python 和 qt 编程更亲和
  4. pyqtgraph 具备更好的图像交互、3D展示等

1.2 pyqtgraph 安装

一般配合 PyQt5 使用,这些都要预先安装好,我们这里只提 pyqtgraph 相关:

pip install pyqtgraph

1.3 pyqtgraph 实例全集

官方专门给出了一个实例集合,包含了展示与源码,非常方便学习,通过以下代码来运行:

import pyqtgraph.examples
pyqtgraph.examples.run()

运行后,会出现如下 GUI 界面

今天我们主要关注实时绘制数据,找到左侧目录中的 "Scrolling plots",单击右侧可以看到源码

双击或者点击下方的 "Run Example" 便可展示运行效果:

特定截图:

2. 实时绘制学习

结合着实例代码和演示效果,我们可以看到有如下不同实时展示模式:

  • 模式1: 从 0 开始固定 x 轴数值范围,数据在该范围内向左移动展示
  • 模式2: 数据带着 x 轴坐标一起向左移动展示
  • 模式3: 固定 x 轴数值右侧范围到 0,数据左移展示
  • 模式4: 左侧固定从 0 开始,数据累积展示
  • 模式5: 数据范围右侧截止到 0,但仍可查看大于 0 范围

2.1 模式1: 固定 x 范围,左移展示数据

2.1.1 模式1效果

2.1.2 实例1代码

我们可以在实例汇总的代码中将该部分代码抽离出来,大致如下:

import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as npwin = pg.GraphicsLayoutWidget(show=True)
win.setWindowTitle('Scrolling Plots Mode 1')p1 = win.addPlot()
data1 = np.random.normal(size=300)curve1 = p1.plot(data1)def update1():global data1, ptr1data1[:-1] = data1[1:]  # shift data in the array one sample left# (see also: np.roll)data1[-1] = np.random.normal()curve1.setData(data1)timer = pg.QtCore.QTimer()
timer.timeout.connect(update1)
timer.start(50)## Start Qt event loop unless running in interactive mode or using pyside.
if __name__ == '__main__':import sysif (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):QtGui.QApplication.instance().exec_()

注意,模式 1 中实时绘制效果的实现,是通过将数据列表中的数据整体左移实现的,关键语句就是 data1[:-1] = data1[1:],再通过计时器来绑定该左移数据的函数,最终达到了展示中的数据动态展示效果。

2.1.3 写成 PlotWidget 形式

总结下模式 1 的原理:x 坐标数据不变化,对应的 y 数据设置个左移变换的函数,计时器信号绑定该左移数据的函数,把 y 数据能实时设置到图中即可。

实例 1 中绘制图的写法比较少见,通常应用是通过 pyqtgraph.PlotWidget.plot() 来实现在控件中作图再添加到 GUI 控件中,所以我们将采用 PlotWidget 的写法来实现模式1的绘制,代码如下:

__author__ = 'Ted'from PyQt5.Qt import *
from pyqtgraph import PlotWidget
from PyQt5 import QtCore
import numpy as np
import pyqtgraph as pqclass Window(QWidget):def __init__(self):super().__init__()# 设置下尺寸self.resize(600,600)# 添加 PlotWidget 控件self.plotWidget_ted = PlotWidget(self)# 设置该控件尺寸和相对位置self.plotWidget_ted.setGeometry(QtCore.QRect(25,25,550,550))# 仿写 mode1 代码中的数据# 生成 300 个正态分布的随机数self.data1 = np.random.normal(size=300)self.curve1 = self.plotWidget_ted.plot(self.data1, name="mode1")# 设定定时器self.timer = pq.QtCore.QTimer()# 定时器信号绑定 update_data 函数self.timer.timeout.connect(self.update_data)# 定时器间隔50ms,可以理解为 50ms 刷新一次数据self.timer.start(50)# 数据左移def update_data(self):self.data1[:-1] = self.data1[1:]self.data1[-1] = np.random.normal()# 数据填充到绘制曲线中self.curve1.setData(self.data1)if __name__ == '__main__':import sys# PyQt5 程序固定写法app = QApplication(sys.argv)# 将绑定了绘图控件的窗口实例化并展示window = Window()window.show()# PyQt5 程序固定写法sys.exit(app.exec())

我们在自己写的代码中重新设置了下窗口尺寸位置,数据还是按照实例中的写法来完成的。

2.1.4 自写模式1效果

2.2 数据随 x 轴一起左移

2.2.1 模式2效果

2.2.2 实例2代码

该模式代码抽离出来大致如下:

import pyqtgraph as pg
from pyqtgraph.Qt import QtCore, QtGui
import numpy as npwin = pg.GraphicsLayoutWidget(show=True)
win.setWindowTitle('pyqtgraph example: Scrolling Plots')p2 = win.addPlot()
data1 = np.random.normal(size=300)curve2 = p2.plot(data1)
ptr1 = 0def update1():global data1, ptr1data1[:-1] = data1[1:]  # shift data in the array one sample leftdata1[-1] = np.random.normal()ptr1 += 1curve2.setData(data1)curve2.setPos(ptr1, 0)timer = pg.QtCore.QTimer()
timer.timeout.connect(update1)
timer.start(50)if __name__ == '__main__':import sysif (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):QtGui.QApplication.instance().exec_()

对比模式1代码,此部分多了个 curve2.setPos(ptr1, 0),通过 Qt 官网中搜索查阅,setPos(x,y) 是将原点设置到 (x,y):

❝ Sets the position of the item to pos, which is in parent coordinates. For items with no parent, pos is in scene coordinates. The position of the item describes its origin (local coordinate (0, 0)) in parent coordinates.

这样我们可以大致理解为,通过设置坐标系相对原点位置来产生 x 轴移动的效果。

2.2.3 写成 PlotWidget 形式

总结下模式 2 的原理: y 数据与模式1相同,设置左移变换的函数,计时器信号绑定该左移数据的函数,把 y 数据能实时设置到图中;x 数据则通过 setPos() 函数随着 y 的变化同步进行设置,产生 x 轴同步移动的效果。

我们继续采用 PlotWidget 的写法来实现模式2的绘制,在模式1基础上添加几行代码即可,为作区分我们把曲线定义为 curve2:

__author__ = 'Ted'from PyQt5.Qt import *
from pyqtgraph import PlotWidget
from PyQt5 import QtCore
import numpy as np
import pyqtgraph as pqclass Window(QWidget):def __init__(self):super().__init__()# 设置下尺寸self.resize(600,600)# 添加 PlotWidget 控件self.plotWidget_ted = PlotWidget(self)# 设置该控件尺寸和相对位置self.plotWidget_ted.setGeometry(QtCore.QRect(25,25,550,550))# 仿写 mode1 代码中的数据# 生成 300 个正态分布的随机数self.data1 = np.random.normal(size=300)self.curve2 = self.plotWidget_ted.plot(self.data1, name="mode2")self.ptr1 = 0# 设定定时器self.timer = pq.QtCore.QTimer()# 定时器信号绑定 update_data 函数self.timer.timeout.connect(self.update_data)# 定时器间隔50ms,可以理解为 50ms 刷新一次数据self.timer.start(50)# 数据左移def update_data(self):self.data1[:-1] = self.data1[1:]self.data1[-1] = np.random.normal()# 数据填充到绘制曲线中self.curve2.setData(self.data1)# x 轴记录点self.ptr1 += 1# 重新设定 x 相关的坐标原点self.curve2.setPos(self.ptr1,0)if __name__ == '__main__':import sys# PyQt5 程序固定写法app = QApplication(sys.argv)# 将绑定了绘图控件的窗口实例化并展示window = Window()window.show()# PyQt5 程序固定写法sys.exit(app.exec())

我们在自己写的代码中重新设置了下窗口尺寸位置,数据还是按照实例中的写法来完成的。

2.2.4 自写模式1效果

3. 小结

今天先只简单整理这两个较简单的实时绘制模式,给定的代码中数据是用的随机正态分布数据,我们结合着模式 1 和 2 的实例代码来分析其原理算法来仿写了常用版本的代码。

掌握模式 1 和模式 2 的用法后,我们便可以对更多的数据来进行动态展示,比如 CPU 占用率、股票实时价格等,配合着 PyQt5 的 GUI 图形界面,那么完全可以用 Python 来写出看着高大上的数据可视化界面了,这个后续我们再继续研究。

qt如何做到实时显示数据_Python 如何实时绘制数据相关推荐

  1. python 插补数据_python 2020中缺少数据插补技术的快速指南

    python 插补数据 Most machine learning algorithms expect complete and clean noise-free datasets, unfortun ...

  2. python处理金融数据_Python 数据分析中金融数据的来源库和简单操作

    金融数据 数据分析离不开数据的获取,这里介绍几种常用的获取金融方面数据的方法. pandas-datareader pandas-datareader 库包含了全球最著名的几家公司所整理的金融数据,这 ...

  3. discard connection丢失数据_python kafka 生产者发送数据的三种方式

    python kafka 生产者发送数据的三种方式 发送方式 同步发送 发送数据耗时最长 有发送数据的状态,不会丢失数据,数据可靠性高 以同步的方式发送消息时,一条一条的发送,对每条消息返回的结果判断 ...

  4. python导入哨兵数据_Python 下载哨兵Sentinel数据(Sentinel-1~3)

    哨兵数据目前应用广泛,空间分辨.光谱分辨率都比较高.目前数据下载部分包括官网和Python程序下载. 其中哨兵1和2数据下载网上已经有非常详细的记录,链接如下:Python中使用sentinelsat ...

  5. python读取mysql中表内数据_Python读取MySQL表数据的方法介绍

    这篇文章主要为大家详细介绍了Python如何读取MySQL数据库表数据,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 本文实例为大家分享了Python读取MySQL数据库表数据的具体代码,供大家参 ...

  6. python代码中怎么增加数据_python 实现数据库中数据添加、查询与更新的示例代码...

    一.前言 最近做web网站的测试,遇到很多需要批量造数据的功能:比如某个页面展示数据条数需要达到10000条进行测试,此时手动构造数据肯定是不可能的,此时只能通过python脚本进行自动构造数据:本次 ...

  7. python 微信数据_python 处理微信对账单数据的实例代码

    下面一段代码给大家介绍python 处理微信对账单数据,具体代码如下所示: #下载对账单并存储到数据库 @app.route("/bill/",methods=["GET ...

  8. python获取erp数据_python自学之路-数据读取

    人家都说人生苦短, 要学Python.我也是看中计算机快速处理数据的优势,非常想学习这门语言,这真要开始了,确实觉得万事开头难,就此记录下这其中点点滴滴. 系统学习有些大海捞针,还是根据自己的实际需要 ...

  9. python出租车数据_Python处理JSON格式数据(出租车轨迹数据)

    1.主要是先通过观察发现JSON数据的规律,我们可以使用Notepad++工具查看JSON数据的结构,了解数据的层次. 即使文件不是真正的json格式,例如有可能是多个json格式放在一起,每一行是一 ...

最新文章

  1. 计算机视觉:让冰冷的机器看懂多彩的世界
  2. OpenCV使用基本算法检测颜色检查器
  3. Jmeter录制app脚本
  4. 理发店管理系统java_美容美发店管理系统的设计与实现(JSP,SQLServer)(含录像)
  5. 块元素、行内块和内联元素_如何删除内联块元素之间的空间?
  6. RedHat gcc编译器版本升级到4.8.2支持C++11标准
  7. java向上向下取整与四舍五入
  8. OpenCart支付宝付款接口(直接到账、担保交易、双接口)
  9. Java中的Object 类的常见方法
  10. Hadoop大数据综合案例4-Hive数据分析
  11. 微雪电子扫码模块使用
  12. NBA球队实力聚类分析
  13. 用 Python 切换输入法
  14. (基础)Promise中then()方法使用,多次调用、链式调用
  15. 【算法】ACO蚂蚁寻路最短路径TSP问题-多篇文章总结
  16. Labview各版本软件下载链接
  17. 2022-2027中国内科缝合线行业应用形势与需求前景预测报告
  18. 设计模式--设配器模式
  19. ArcGIS JS API 4.x(二) 加载 3.x所说的动态地图服务图层
  20. 用 React+Redux+Immutable 做俄罗斯方块

热门文章

  1. SAP CAM - Cloud Access Manager
  2. 使用纯粹的ABAP位操作实现两个整数相加
  3. 在S/4HANA扩展字段的Available Fields列表里,看不到自己创建的扩展字段该怎么办
  4. SAP Fiori Elements - Smart table add button debug 2 setDirty
  5. 如何在CRM和C4C中用代码判断当前是否处于configuration模式
  6. 推荐一个在线图片处理神奇,图片处理绝大多数需求,都能在浏览器里搞定
  7. Cloud for Customer的事件处理队列
  8. ubuntu上Nginx的配置
  9. 打印product所有attachment 具体信息的小工具
  10. Use BAdI - call_workitem_exit workflow