Pyqt+matplotlib 实现实时画图案例

作者:苏格拉倒 时间:2022-01-06 12:52:23 

需求分析:

项目中根据测得的数据在界面上实时绘制

运行环境:

Python 3.7 + Matplotlib 3.0.2 + PyQt 5

matplot官网给的相应的例子:


import sys
import time
import numpy as np
from matplotlib.backends.qt_compat import QtCore, QtWidgets, is_pyqt5
if is_pyqt5():
 from matplotlib.backends.backend_qt5agg import (
   FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
else:
 from matplotlib.backends.backend_qt4agg import (
   FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure
class ApplicationWindow(QtWidgets.QMainWindow):
 def __init__(self):
   super().__init__()
   self._main = QtWidgets.QWidget()
   self.setCentralWidget(self._main)
   layout = QtWidgets.QVBoxLayout(self._main)
   static_canvas = FigureCanvas(Figure(figsize=(5, 3)))
   layout.addWidget(static_canvas)
   self.addToolBar(NavigationToolbar(static_canvas, self))
   dynamic_canvas = FigureCanvas(Figure(figsize=(5, 3)))
   layout.addWidget(dynamic_canvas)
   self.addToolBar(QtCore.Qt.BottomToolBarArea,
           NavigationToolbar(dynamic_canvas, self))
   self._static_ax = static_canvas.figure.subplots()
   t = np.linspace(0, 10, 501)
   self._static_ax.plot(t, np.tan(t), ".")
   self._dynamic_ax = dynamic_canvas.figure.subplots()
   self._timer = dynamic_canvas.new_timer(
     100, [(self._update_canvas, (), {})])
   self._timer.start()
 def _update_canvas(self):
   self._dynamic_ax.clear()
   t = np.linspace(0, 10, 101)
   # Shift the sinusoid as a function of time.
   self._dynamic_ax.plot(t, np.sin(t + time.time()))
   self._dynamic_ax.figure.canvas.draw()
if __name__ == "__main__":
 qapp = QtWidgets.QApplication(sys.argv)
 app = ApplicationWindow()
 app.show()
 qapp.exec_()

Pyqt+matplotlib 实现实时画图案例

上图中的散点为静止的,下面的图为动态的,类似行波,一直在行走,是应为用了**self._dynamic_ax.plot(t, np.sin(t + time.time()))**函数,但是这个和我想得实时画图不太一样,在项目中要根据生成的数据实时绘图,因此x轴的元素和y轴的元素个数是逐渐增加的。

通过阅读上述 _update_canvas 函数代码以及 dynamic_canvas.new_timer 可以使得每次调用_update_canvas是的相应的x的元素和y轴的元素增加更改后的代码如下:


import sys
import time
import numpy as np
from matplotlib.backends.qt_compat import QtCore, QtWidgets, is_pyqt5
if is_pyqt5():
 from matplotlib.backends.backend_qt5agg import (
   FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
else:
 from matplotlib.backends.backend_qt4agg import (
   FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure
class ApplicationWindow(QtWidgets.QMainWindow):
 def __init__(self):
   super().__init__()
   self._main = QtWidgets.QWidget()
   self.setCentralWidget(self._main)
   layout = QtWidgets.QVBoxLayout(self._main)
   static_canvas = FigureCanvas(Figure(figsize=(5, 3)))
   layout.addWidget(static_canvas)
   self.addToolBar(NavigationToolbar(static_canvas, self))
   dynamic_canvas = FigureCanvas(Figure(figsize=(5, 3)))
   layout.addWidget(dynamic_canvas)
   self.addToolBar(QtCore.Qt.BottomToolBarArea,
           NavigationToolbar(dynamic_canvas, self))
   self._static_ax = static_canvas.figure.subplots()
   t = np.linspace(0, 10, 501)
   self._static_ax.plot(t, np.tan(t), ".")
   self.x = [] #建立空的x轴数组和y轴数组
   self.y = []
   self.n = 0
   self._dynamic_ax = dynamic_canvas.figure.subplots()
   self._timer = dynamic_canvas.new_timer(
     100, [(self._update_canvas, (), {})])
   self._timer.start()

def _update_canvas(self):
   self.n += 1
   if self.n == 200:      #画200个点就停止,根据实际情况确定终止条件
     self._timer.stop()  
   self._dynamic_ax.clear()
   self.x.append(np.pi/100*self.n) #x加入一个值,后一个值比前一个大pi/100
   xx = np.array(self.x)
   # t = np.linspace(0, 10, 101)
   # Shift the sinusoid as a function of time.
   self._dynamic_ax.plot(xx, np.sin(xx))
   self._dynamic_ax.set_xlim(0,7)
   self._dynamic_ax.set_ylim(-1,1)
   self._dynamic_ax.figure.canvas.draw()
if __name__ == "__main__":
 qapp = QtWidgets.QApplication(sys.argv)
 app = ApplicationWindow()
 app.show()
 qapp.exec_()

Pyqt+matplotlib 实现实时画图案例

上面的图仍然静止,下面的可以实时显示

Pyqt+matplotlib 实现实时画图案例

补充:pyqtgraph实时绘图出现无法刷新问题

pyqtgraph实时绘图时,会概率出现无法实时刷新绘制图,原因是


while True:
 ......
 update()  # 通过 plotitem.setData()更新数据
 ......

这里使用的是while循环,不断的更新数据概率出现绘图不刷新和操作不响应(最小化操作会高概率出现该问题)

解决方法1:

我使用的是PlotWidget,remove后再addwidget,然后再重新绘制

解决方法2:

不使用while循环,使用QTime定时器


t = QTimer()
t.timeout.connect(self.update)
t.start(10)

两种方法都可以解决这个问题,推荐方法2

据说使用while循环,需要在更新数据之后调用pg.QtGui.QApplication.processEvents()才能确保正常,这个本人试了不行,可能是我这边的原因吧

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。如有错误或未考虑完全的地方,望不吝赐教。

来源:https://blog.csdn.net/weixin_44405720/article/details/88882077

标签:Pyqt,matplotlib,画图
0
投稿

猜你喜欢

  • 从绘画语言的发展,看视觉设计风格

    2008-08-03 17:11:00
  • Python实现CAN报文转换工具教程

    2022-06-13 02:34:06
  • python的几种开发工具介绍

    2021-09-28 01:54:44
  • 教你制作1px边框表格的四种方法

    2008-10-04 10:16:00
  • 用Python的Django框架完成视频处理任务的教程

    2022-05-07 05:38:25
  • Flask-Vue前后端分离的全过程讲解

    2022-08-07 23:51:11
  • Python/Django后端使用PIL Image生成头像缩略图

    2021-12-18 09:46:27
  • php网络安全中命令执行漏洞的产生及本质探究

    2023-05-30 05:34:31
  • Firefox插件推荐:CSS Usage

    2009-10-26 18:44:00
  • python检查URL是否正常访问的小技巧

    2022-02-23 09:23:56
  • Python中的变量与常量

    2022-01-14 22:26:43
  • 浅谈图表参数化设计

    2010-08-29 18:03:00
  • Python3使用腾讯云文字识别(腾讯OCR)提取图片中的文字内容实例详解

    2023-11-16 22:45:05
  • python字符串的index和find的区别详解

    2022-09-17 17:58:47
  • ThinkPHP php 框架学习笔记

    2023-09-10 08:20:32
  • python爬虫获取新浪新闻教学

    2021-10-13 11:15:41
  • Python实现聚类K-means算法详解

    2023-04-22 07:48:36
  • OpenCV半小时掌握基本操作之色彩空间

    2021-01-05 05:27:31
  • Django如何使用jwt获取用户信息

    2022-07-06 10:08:34
  • Python文件的应用之序列化与反序列化详解

    2021-06-19 22:20:45
  • asp之家 网络编程 m.aspxhome.com