Python 在pyqt5接口中动态更新matplotlib画布
我有一个非常简单的程序,它的结构必须保留下来,这是练习的一个条件 我们从一个按钮和画布组成的界面开始,如上图所示 单击按钮后,将启动后台任务,该任务将调用名为动画的函数。在这里,我们开始一个过程,每次都会生成随机数据。 每次有新的x和y变量时,我们都要更新绘图 代码如下:Python 在pyqt5接口中动态更新matplotlib画布,python,pyqt,pyqt5,Python,Pyqt,Pyqt5,我有一个非常简单的程序,它的结构必须保留下来,这是练习的一个条件 我们从一个按钮和画布组成的界面开始,如上图所示 单击按钮后,将启动后台任务,该任务将调用名为动画的函数。在这里,我们开始一个过程,每次都会生成随机数据。 每次有新的x和y变量时,我们都要更新绘图 代码如下: from PyQt5 import QtCore, QtWidgets from mplwidget import MplWidget import threading import time import numpy as
from PyQt5 import QtCore, QtWidgets
from mplwidget import MplWidget
import threading
import time
import numpy as np
import sys
class RandomDataGeneration():
"""
Mandatory Class. This Class must exist.
"""
def __init__(self):
pass
def data_generation(self):
while True:
waiting_time = np.random.randint(1,4) # waiting time is given by a random number.
print(waiting_time)
time.sleep(waiting_time)
self.x = np.random.rand(10)
self.y = np.random.rand(10)
print(self.x)
print(self.y)
#self.update_plot()
def update_plot(self):
self.MplWidget.canvas.axes.clear()
self.MplWidget.canvas.axes.set_title('GRAPH')
self.MplWidget.canvas.axes.plot(x, y, marker='.', linestyle='')
self.MplWidget.canvas.axes.legend(('random'), loc='upper right')
self.MplWidget.canvas.draw()
def animation():
"""
This function initiates the RandomDataGeneration
"""
app = RandomDataGeneration()
app.data_generation()
class Ui_MainWindow():
def __init__(self):
super().__init__()
def start_download(self):
download_info = threading.Thread(target=animation)
download_info.start()
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1280, 1024)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(880, 80, 221, 32))
self.pushButton.setObjectName("pushButton")
self.MplWidget = MplWidget(self.centralwidget)
self.MplWidget.setGeometry(QtCore.QRect(49, 39, 771, 551))
self.MplWidget.setObjectName("MplWidget")
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "PushButton"))
self.pushButton.clicked.connect(self.start_download)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
要运行代码,必须在同一文件夹中包含以下名为mplwidget.py的代码
由于您正在创建一个pyqt5应用程序,我想您最好的选择是为阻塞部分使用一个QThread,并在每次生成新数据时发出一个信号。一种方法是使RandomDataGeneration成为QThread的一个子类并实现run,例如 要使用该线程,您可以将QMainWindow子类化,并在其中创建RandomDataGeneration的实例。子类化QMainWindow还有一个额外的优点,即您可以将gui设置和信号插槽连接移动到其中,例如
class MyMainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.download_thread = RandomDataGeneration(self)
self.download_thread.new_data.connect(self.plot_data)
self.ui.pushButton.clicked.connect(self.start_download)
def start_download(self):
if not self.download_thread.isRunning():
self.download_thread.start()
def plot_data(self):
self.ui.MplWidget.update_plot(self.download_thread.x, self.download_thread.y)
然后,主体部分成为
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = MyMainWindow()
MainWindow.show()
sys.exit(app.exec_())
允许您更改哪些位?例如,您是否可以更改RandomDataGeneration的实现?原则上,我们可以更改RandomDataGeneration中除数据生成之外的所有内容。更新图已经是我的贡献了。
class MyMainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.download_thread = RandomDataGeneration(self)
self.download_thread.new_data.connect(self.plot_data)
self.ui.pushButton.clicked.connect(self.start_download)
def start_download(self):
if not self.download_thread.isRunning():
self.download_thread.start()
def plot_data(self):
self.ui.MplWidget.update_plot(self.download_thread.x, self.download_thread.y)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
MainWindow = MyMainWindow()
MainWindow.show()
sys.exit(app.exec_())