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_()
上图中的散点为静止的,下面的图为动态的,类似行波,一直在行走,是应为用了**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_()
上面的图仍然静止,下面的可以实时显示
补充: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


猜你喜欢
- 数据可以帮助我们描述这个世界、阐释自己的想法和展示自己的成果,但如果只有单调乏味的文本和数字,我们却往往能难抓住观众的眼球。而很多时候,一张
- 方法一:插入断点,Debug运行在欲查看变量值的语句前,插入断点,Debug运行。之后,就在Debug面板下,可以查看各变量值,然后还可按F
- 用 Python 关机你肯定听过或者实践过,那么用 Python 开机呢?这是一个神奇的方法,教你如何用 Python 来开机。GitHub
- 最近在备考软考的软件设计师考试,在学习过程遇到很多于计算机基础计算相关的知识点,正好最近在学Go语言,所以就把计算的方式用Go语言实现一下。
- 我的原数据库是3.23版本的.前几天因为一个论坛转移.必须用5.1的.于是就是升级了数据库.论坛是正常的.可以是原来的一个老库因为是3.23
- SQL Server Sa用户相信大家都有一定的理解,下面就为您介绍SQL Server 2000身份验证模式的修改方法及SQL Serve
- div和span、relative和absolute、display和visibility是很容易混淆和弄错的HTML标签与CSS属性,简单
- 一 创建mappingPUT test{ "mappings": { "
- 1.理解mask()和setmask()一般是在pyqt绘图时常见,而且在显示不规则图形时更是常见。参考书籍上说:setMask()函数的作
- fuzzywuzzy 可以计算两个字符串之间的相似度,它依据 Levenshtein Distance 算法来进行计算。
- 一、在javascript中嵌入php代码javascript若是通过js文件包含进来的,那么js文件中也可以直接写php代码,
- 本文为大家分享了JavaScript实现省市联动过程中bug的解决方法,供大家参考,具体内容如下先把实现省市联动遇到的问题描述一下1.1.原
- 一、基本使用selenium 的基本使用步骤:打开浏览器;获取浏览器页面的特定内容;控制浏览器页面上的控件,如向一个文本框中输入一个字符串;
- 疫情终于有所好转了,感谢所有的为之奋斗的白衣天使们,你们是最棒的!赞!白衣天使们在前线奋战,我们也总不能总在家里躺着做贡献,也要加强学习,争
- 本文实例为大家分享了OpenCV基于ORB算法实现角点检测的具体代码,供大家参考,具体内容如下ORB算法是FAST算法和BRIEF算法的结合
- 在写python程序时,对于可变对象和不可变对象这里理解不深,导致总会犯一些细节错误。以下面的程序举例:ab = {'a':
- LRULRU(Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访
- 客户端: <%@ Page Language="C#" AutoEventWireup="true&qu
- 主旨在日常工作中,我们会经常且频繁的使用excel表格,那么我们是否可以通过python来操作excel表格,让其自动化的来代替我们的工作呢
- 使用continue跳过本次写循环就可以了#文本内容Yesterday when I was young昨日当我年少轻狂The tastin