我目前与Matplotlib结合使用PyQt5时遇到了一个我完全不了解的问题。基本上,我只想在同一图中绘制由QPushButton触发的不同曲线。我在下面的最小工作示例中重新创建了该问题。
期望:
每次点击“绘图”按钮时,当前图形都会用新行更新
结果:
第一个图正常工作,但是之后该图不再使用正确的数据更新。如果关闭该图并再次按下该按钮,该图将再次开始工作。 如果代码更改为
fig = plt.figure()
也就是说,如果每次创建新图形,它都会按预期工作。这是错误还是我以某种方式弄错了?
以下软件包用于最小工作示例:
matplotlib==3.1.3
PyQt5==5.14.1
pyqt5-tools==5.13.0.1.5
示例代码:
import matplotlib.pyplot as plt
import numpy as np
import sys
from PyQt5 import QtWidgets
class MaterialBrowser(QtWidgets.QMainWindow):
def __init__(self):
super(MaterialBrowser, self).__init__()
self.setEnabled(True)
self.setGeometry(0, 0, 543, 700)
self.setMinimumSize(543, 400)
self.save_button = QtWidgets.QPushButton(self)
self.save_button.setGeometry(100, 100, 110, 32)
self.save_button.setObjectName("plot_button")
self.save_button.setText("Plot")
self.save_button.clicked.connect(self.plot_bhcurve)
self.show()
def plot_bhcurve(self):
t = np.arange(0.0, 2.0, 0.01)
omega = np.random.randint(2, 50)
s = 1 + np.sin(2 * np.pi * omega* t)
fig = plt.figure(num='MYFIGURE')
ax = fig.gca()
ax.plot(t, s, '.-', label=f'mycurve{omega}')
ax.grid(True, which="both")
ax.set_xlabel('Field Strength (A/m)')
ax.set_ylabel('Flux Density (T)')
ax.set_xlim(left=0)
ax.set_ylim(bottom=0)
plt.legend()
plt.show()
app = QtWidgets.QApplication(sys.argv)
materialbrowser = MaterialBrowser()
sys.exit(app.exec_())
答案 0 :(得分:1)
将Matplotlib集成到PyQt中时,永远不要使用matplotlib.pyplot
模块,因为这会创建它自己的事件并维护图形和轴的列表。它与Qt冲突。
关于如何将Matplotlib嵌入PyQt here中,有一个很好的例子。基于此,我已经修改了您的示例。
import numpy as np
import sys
from PyQt5 import QtWidgets
from matplotlib.backends.backend_qt5agg import (
FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure
class MaterialBrowser(QtWidgets.QMainWindow):
def __init__(self):
super(MaterialBrowser, self).__init__()
self.setEnabled(True)
self.setGeometry(0, 0, 543, 700)
self.setMinimumSize(543, 400)
self.main_widget = QtWidgets.QWidget()
self.setCentralWidget(self.main_widget)
self.main_layout = QtWidgets.QVBoxLayout()
self.main_widget.setLayout(self.main_layout)
self.save_button = QtWidgets.QPushButton(self)
self.save_button.setGeometry(100, 100, 110, 32)
self.save_button.setObjectName("plot_button")
self.save_button.setText("Plot")
self.save_button.clicked.connect(self.plot_bhcurve)
self.main_layout.addWidget(self.save_button)
self._fig = Figure(figsize=(5, 3))
self._canvas = FigureCanvas(self._fig)
self.main_layout.addWidget(self._canvas)
self._axes = self._fig.subplots()
self._axes.grid(True, which="both")
self._axes.set_xlabel('Field Strength (A/m)')
self._axes.set_ylabel('Flux Density (T)')
self._axes.set_xlim(left=0)
self._axes.set_ylim(bottom=0)
self._axes.legend()
self.addToolBar(NavigationToolbar(self._canvas, self))
self.show()
def plot_bhcurve(self):
print("plotting")
t = np.arange(0.0, 2.0, 0.01)
omega = np.random.randint(2, 50)
s = 1 + np.sin(2 * np.pi * omega* t)
self._axes.plot(t, s, '.-', label=f'mycurve{omega}')
self._canvas.draw()
app = QtWidgets.QApplication(sys.argv)
materialbrowser = MaterialBrowser()
sys.exit(app.exec_())
顺便说一句,我强烈建议您使用Qt布局来布局您的小部件。