下面是“PyQt+Matplotlib 实现实时画图案例”的完整攻略。
1. 环境搭建
首先需要搭建 Python 环境和安装 PyQt 和 Matplotlib 库,可以使用 pip 进行安装,命令如下:
pip install pyqt5, matplotlib
2. 定义Qt窗口和Matplotlib画布
我们需要一个Qt窗口来显示Matplotlib画布,下面是一个示例代码:
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QSizePolicy, QVBoxLayout, QWidget
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
class MyMainWindow(QMainWindow):
def __init__(self):
super().__init__()
# 创建一个Matplotlib画布并添加到Qt窗口
self.myCanvas = MyMplCanvas(width=5, height=4, dpi=100)
self.setCentralWidget(self.myCanvas)
class MyMplCanvas(FigureCanvas):
def __init__(self, width, height, dpi):
# 创建一个Matplotlib Figure对象
self.fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = self.fig.add_subplot(111)
# 初始化控件
FigureCanvas.__init__(self, self.fig)
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.updateGeometry()
该代码定义了一个MyMainWindow类作为Qt窗口,其中包含一个成员变量myCanvas,该成员变量是自定义的MyMplCanvas类,表示一个Matplotlib画布。MyMplCanvas类继承自 FigureCanvas,通过Figure对象和add_subplot方法创建了一个Matplotlib坐标系,并将其添加到画布中。
3. 实现动态数据更新
我们希望在Matplotlib画布上实时绘制数据的变化,并在Qt窗口上显示出来,下面是一个示例代码:
import numpy as np
import time
class MyThread(QtCore.QThread):
update_data = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(MyThread, self).__init__(parent)
self.data = np.zeros(100)
self.data_index = 0
def run(self):
while True:
# 模拟数据更新
self.data[self.data_index] = np.random.random()
self.data_index += 1
if self.data_index >= len(self.data):
self.data_index = 0
# 发送更新信号
self.update_data.emit()
# 线程暂停100毫秒
time.sleep(0.1)
class MyMainWindow(QMainWindow):
def __init__(self):
super().__init__()
# 创建线程并连接信号
self.myThread = MyThread()
self.myThread.update_data.connect(self.update_data)
# 启动线程
self.myThread.start()
def update_data(self):
# 从线程中获取数据,更新Matplotlib画布
data = self.myThread.data
self.myCanvas.axes.clear()
self.myCanvas.axes.plot(data)
self.myCanvas.draw()
该示例代码中定义了一个 MyThread 类并继承自Qt线程类,该线程类每隔100毫秒模拟一次数据的更新,更新后通过信号 emit 发送更新信号。 MyMainWindow 类定义了一个update_data函数,当线程发出更新信号后,该函数会从线程中获取数据并在Matplotlib画布上更新。
4. 示例展示
通过上述的三个步骤,我们已经实现了一个简单的实时画图案例。下面是一个完整的示例代码:
import sys
import numpy as np
import time
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QSizePolicy, QVBoxLayout, QWidget
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
class MyThread(QtCore.QThread):
update_data = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(MyThread, self).__init__(parent)
self.data = np.zeros(100)
self.data_index = 0
def run(self):
while True:
# 模拟数据更新
self.data[self.data_index] = np.random.random()
self.data_index += 1
if self.data_index >= len(self.data):
self.data_index = 0
# 发送更新信号
self.update_data.emit()
# 线程暂停100毫秒
time.sleep(0.1)
class MyMplCanvas(FigureCanvas):
def __init__(self, width, height, dpi):
# 创建一个Matplotlib Figure对象
self.fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = self.fig.add_subplot(111)
# 初始化控件
FigureCanvas.__init__(self, self.fig)
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.updateGeometry()
class MyMainWindow(QMainWindow):
def __init__(self):
super().__init__()
# 创建一个Matplotlib画布并添加到Qt窗口
self.myCanvas = MyMplCanvas(width=5, height=4, dpi=100)
self.setCentralWidget(self.myCanvas)
# 创建线程并连接信号
self.myThread = MyThread()
self.myThread.update_data.connect(self.update_data)
# 启动线程
self.myThread.start()
def update_data(self):
# 从线程中获取数据,更新Matplotlib画布
data = self.myThread.data
self.myCanvas.axes.clear()
self.myCanvas.axes.plot(data)
self.myCanvas.draw()
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWindow = MyMainWindow()
mainWindow.show()
sys.exit(app.exec_())
在上述示例程序中,我们创建了一个Qt窗口,该窗口中包含一个Matplotlib画布,并创建了一个线程,每隔100毫秒更新数据并发送更新信号,Qt窗口接收到信号后会更新Matplotlib画布中的数据并进行显示。运行该程序,可以看到实时绘图的效果。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Pyqt+matplotlib 实现实时画图案例 - Python技术站