Pyqt+matplotlib 实现实时画图案例
需求分析:
项目中根据测得的数据在界面上实时绘制
运行环境:
Python3.7+Matplotlib3.0.2+PyQt5
matplot官网给的相应的例子:
importsys
importtime
importnumpyasnp
frommatplotlib.backends.qt_compatimportQtCore,QtWidgets,is_pyqt5
ifis_pyqt5():
frommatplotlib.backends.backend_qt5aggimport(
FigureCanvas,NavigationToolbar2QTasNavigationToolbar)
else:
frommatplotlib.backends.backend_qt4aggimport(
FigureCanvas,NavigationToolbar2QTasNavigationToolbar)
frommatplotlib.figureimportFigure
classApplicationWindow(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)
#Shiftthesinusoidasafunctionoftime.
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轴的元素增加更改后的代码如下:
importsys
importtime
importnumpyasnp
frommatplotlib.backends.qt_compatimportQtCore,QtWidgets,is_pyqt5
ifis_pyqt5():
frommatplotlib.backends.backend_qt5aggimport(
FigureCanvas,NavigationToolbar2QTasNavigationToolbar)
else:
frommatplotlib.backends.backend_qt4aggimport(
FigureCanvas,NavigationToolbar2QTasNavigationToolbar)
frommatplotlib.figureimportFigure
classApplicationWindow(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
ifself.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)
#Shiftthesinusoidasafunctionoftime.
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实时绘图时,会概率出现无法实时刷新绘制图,原因是
whileTrue: ...... 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()才能确保正常,这个本人试了不行,可能是我这边的原因吧
以上为个人经验,希望能给大家一个参考,也希望大家多多支持毛票票。如有错误或未考虑完全的地方,望不吝赐教。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。