qt如何做到实时显示数据_Python 如何实时绘制数据
提到 GUI 繪圖,大家可能第一反應(yīng)是 OpenGL 和 Matplotlib,但其實基于 Qt 平臺還有個功能強大的 pyqtgraph 繪圖庫,不僅支持豐富的圖形種類,還能實時更新繪圖數(shù)據(jù)并進行交互式操作。
不同于網(wǎng)上其他文章或代碼講解,今天我們集中只關(guān)注實時繪制數(shù)據(jù)功能的實現(xiàn)。為了更精準(zhǔn)學(xué)習(xí)該 pyqtgraph 模塊功能,我們將參考官方給出的實例來邊學(xué)邊練。
1. pyqtgraph 簡介
1.1 pyqtgraph 特點
關(guān)于 pyqtgraph 與 Matplotlib 的對比,大致要點如下:
1.2 pyqtgraph 安裝
一般配合 PyQt5 使用,這些都要預(yù)先安裝好,我們這里只提 pyqtgraph 相關(guān):
pip install pyqtgraph1.3 pyqtgraph 實例全集
官方專門給出了一個實例集合,包含了展示與源碼,非常方便學(xué)習(xí),通過以下代碼來運行:
import pyqtgraph.examples pyqtgraph.examples.run()運行后,會出現(xiàn)如下 GUI 界面
今天我們主要關(guān)注實時繪制數(shù)據(jù),找到左側(cè)目錄中的 "Scrolling plots",單擊右側(cè)可以看到源碼
雙擊或者點擊下方的 "Run Example" 便可展示運行效果:
特定截圖:
2. 實時繪制學(xué)習(xí)
結(jié)合著實例代碼和演示效果,我們可以看到有如下不同實時展示模式:
- 模式1: 從 0 開始固定 x 軸數(shù)值范圍,數(shù)據(jù)在該范圍內(nèi)向左移動展示
- 模式2: 數(shù)據(jù)帶著 x 軸坐標(biāo)一起向左移動展示
- 模式3: 固定 x 軸數(shù)值右側(cè)范圍到 0,數(shù)據(jù)左移展示
- 模式4: 左側(cè)固定從 0 開始,數(shù)據(jù)累積展示
- 模式5: 數(shù)據(jù)范圍右側(cè)截止到 0,但仍可查看大于 0 范圍
2.1 模式1: 固定 x 范圍,左移展示數(shù)據(jù)
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 中實時繪制效果的實現(xiàn),是通過將數(shù)據(jù)列表中的數(shù)據(jù)整體左移實現(xiàn)的,關(guān)鍵語句就是 data1[:-1] = data1[1:],再通過計時器來綁定該左移數(shù)據(jù)的函數(shù),最終達到了展示中的數(shù)據(jù)動態(tài)展示效果。
2.1.3 寫成 PlotWidget 形式
總結(jié)下模式 1 的原理:x 坐標(biāo)數(shù)據(jù)不變化,對應(yīng)的 y 數(shù)據(jù)設(shè)置個左移變換的函數(shù),計時器信號綁定該左移數(shù)據(jù)的函數(shù),把 y 數(shù)據(jù)能實時設(shè)置到圖中即可。
實例 1 中繪制圖的寫法比較少見,通常應(yīng)用是通過 pyqtgraph.PlotWidget.plot() 來實現(xiàn)在控件中作圖再添加到 GUI 控件中,所以我們將采用 PlotWidget 的寫法來實現(xiàn)模式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__()# 設(shè)置下尺寸self.resize(600,600)# 添加 PlotWidget 控件self.plotWidget_ted = PlotWidget(self)# 設(shè)置該控件尺寸和相對位置self.plotWidget_ted.setGeometry(QtCore.QRect(25,25,550,550))# 仿寫 mode1 代碼中的數(shù)據(jù)# 生成 300 個正態(tài)分布的隨機數(shù)self.data1 = np.random.normal(size=300)self.curve1 = self.plotWidget_ted.plot(self.data1, name="mode1")# 設(shè)定定時器self.timer = pq.QtCore.QTimer()# 定時器信號綁定 update_data 函數(shù)self.timer.timeout.connect(self.update_data)# 定時器間隔50ms,可以理解為 50ms 刷新一次數(shù)據(jù)self.timer.start(50)# 數(shù)據(jù)左移def update_data(self):self.data1[:-1] = self.data1[1:]self.data1[-1] = np.random.normal()# 數(shù)據(jù)填充到繪制曲線中self.curve1.setData(self.data1)if __name__ == '__main__':import sys# PyQt5 程序固定寫法app = QApplication(sys.argv)# 將綁定了繪圖控件的窗口實例化并展示window = Window()window.show()# PyQt5 程序固定寫法sys.exit(app.exec())我們在自己寫的代碼中重新設(shè)置了下窗口尺寸位置,數(shù)據(jù)還是按照實例中的寫法來完成的。
2.1.4 自寫模式1效果
2.2 數(shù)據(jù)隨 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 官網(wǎng)中搜索查閱,setPos(x,y) 是將原點設(shè)置到 (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.?
這樣我們可以大致理解為,通過設(shè)置坐標(biāo)系相對原點位置來產(chǎn)生 x 軸移動的效果。
2.2.3 寫成 PlotWidget 形式
總結(jié)下模式 2 的原理: y 數(shù)據(jù)與模式1相同,設(shè)置左移變換的函數(shù),計時器信號綁定該左移數(shù)據(jù)的函數(shù),把 y 數(shù)據(jù)能實時設(shè)置到圖中;x 數(shù)據(jù)則通過 setPos() 函數(shù)隨著 y 的變化同步進行設(shè)置,產(chǎn)生 x 軸同步移動的效果。
我們繼續(xù)采用 PlotWidget 的寫法來實現(xiàn)模式2的繪制,在模式1基礎(chǔ)上添加幾行代碼即可,為作區(qū)分我們把曲線定義為 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__()# 設(shè)置下尺寸self.resize(600,600)# 添加 PlotWidget 控件self.plotWidget_ted = PlotWidget(self)# 設(shè)置該控件尺寸和相對位置self.plotWidget_ted.setGeometry(QtCore.QRect(25,25,550,550))# 仿寫 mode1 代碼中的數(shù)據(jù)# 生成 300 個正態(tài)分布的隨機數(shù)self.data1 = np.random.normal(size=300)self.curve2 = self.plotWidget_ted.plot(self.data1, name="mode2")self.ptr1 = 0# 設(shè)定定時器self.timer = pq.QtCore.QTimer()# 定時器信號綁定 update_data 函數(shù)self.timer.timeout.connect(self.update_data)# 定時器間隔50ms,可以理解為 50ms 刷新一次數(shù)據(jù)self.timer.start(50)# 數(shù)據(jù)左移def update_data(self):self.data1[:-1] = self.data1[1:]self.data1[-1] = np.random.normal()# 數(shù)據(jù)填充到繪制曲線中self.curve2.setData(self.data1)# x 軸記錄點self.ptr1 += 1# 重新設(shè)定 x 相關(guān)的坐標(biāo)原點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())我們在自己寫的代碼中重新設(shè)置了下窗口尺寸位置,數(shù)據(jù)還是按照實例中的寫法來完成的。
2.2.4 自寫模式1效果
3. 小結(jié)
今天先只簡單整理這兩個較簡單的實時繪制模式,給定的代碼中數(shù)據(jù)是用的隨機正態(tài)分布數(shù)據(jù),我們結(jié)合著模式 1 和 2 的實例代碼來分析其原理算法來仿寫了常用版本的代碼。
掌握模式 1 和模式 2 的用法后,我們便可以對更多的數(shù)據(jù)來進行動態(tài)展示,比如 CPU 占用率、股票實時價格等,配合著 PyQt5 的 GUI 圖形界面,那么完全可以用 Python 來寫出看著高大上的數(shù)據(jù)可視化界面了,這個后續(xù)我們再繼續(xù)研究。
總結(jié)
以上是生活随笔為你收集整理的qt如何做到实时显示数据_Python 如何实时绘制数据的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 连接编码器_编码器与PLC的接线
- 下一篇: 以下哪个不是python财经数据接口工具