PyQt5与matplotlib是非常流行的Python图形库,但在使用matplotlib画图时会出现不刷新的情况。本篇攻略将详细介绍解决matplotlib画图不刷新的问题。
问题描述
使用matplotlib
画图时,当图形放大或缩小时,图形内容会被拉伸或扭曲,而这是matplotlib
内在的特性。当尝试通过PyQt5
来实现图形界面时,我们通常会使用matplotlib
嵌入到PyQt5
的窗口控件中。但是,当窗口的大小改变时,控制台会输出一段错误信息"QPixmap: Cannot create a QPixmap when no GUI is being used",同时无法刷新图形。这是由于没有指定Qt
的事件循环,导致matplotlib
无法操作窗口。
解决方案
方法1:使用多线程
解决matplotlib
无法操作窗口的一种方式是使用多线程。要在PyQt5
中实现多线程,我们可以使用QThread
类来创建一个新线程,并将matplotlib
图形绘制在该线程中,以保证窗口控件能正常刷新。
from PyQt5.QtCore import Qt, QThread, pyqtSignal
from PyQt5.QtWidgets import QWidget, QPushButton, QVBoxLayout
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import numpy as np
class PlotThread(QThread):
plot_signal = pyqtSignal(object)
def __init__(self, parent=None):
super().__init__(parent)
def run(self):
fig = Figure()
ax = fig.add_subplot(111)
x = np.linspace(0, 10, 1000)
y = np.sin(x)
ax.plot(x, y)
self.plot_signal.emit(fig)
以上是继承QThread
类的一个简单的线程类。线程的run
方法是需要重写的方法,调用plot_sin
函数绘制图形。需要注意的是,由于不能直接操作matplotlib
相关操作,我们需要使用pyqtSignal
信号来将绘图数据发送回主线程。
class MyApp(QWidget):
def __init__(self):
super().__init__()
self.button = QPushButton('Plot')
self.canvas = FigureCanvas(Figure())
self.layout = QVBoxLayout()
self.layout.addWidget(self.button)
self.layout.addWidget(self.canvas)
self.setLayout(self.layout)
self.button.clicked.connect(self.plot)
def plot(self):
self.plot_thread = PlotThread()
self.plot_thread.plot_signal.connect(self.plot_finished)
self.plot_thread.start()
def plot_finished(self, fig):
self.canvas.figure = fig
self.canvas.draw()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())
以上是将QThread
类线程嵌入到PyQt5
的窗口控件中的简单示例。
方法2:使用timer
槽函数
另一种使用PyQt5
解决matplotlib
画图不刷新的问题的方法是使用timer
槽函数。QTimer
类可以周期性地触发自定义的槽函数,这可以确保窗口控件能够定期刷新并绘制图像。
from PyQt5.QtCore import QTimer
class MyApp(QWidget):
def __init__(self):
super().__init__()
self.button = QPushButton('Plot')
self.canvas = FigureCanvas(Figure())
self.layout = QVBoxLayout()
self.layout.addWidget(self.button)
self.layout.addWidget(self.canvas)
self.setLayout(self.layout)
self.button.clicked.connect(self.plot)
self.timer = QTimer(self)
self.timer.timeout.connect(self.update_figure)
def plot(self):
# 绘制图形
x = np.linspace(0, 10, 1000)
y = np.sin(x)
self.ax.plot(x, y)
self.canvas.draw()
# 启动定时器
self.timer.start(100)
def update_figure(self):
# 刷新图形
self.canvas.draw()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())
结论
以上是两种可以解决PyQt5
中matplotlib
画图不刷新的方法。第一种方法通过使用多线程实现图形绘制,而第二种方法则使用timer
槽函数来定期刷新图形。无论哪种方法都可以让我们在PyQt5
中使用matplotlib
绘制图形,并实时刷新。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:PyQt5 matplotlib画图不刷新的解决方案 - Python技术站