這是我的一段代碼的簡單 MRE,如果您能幫助我,請提前感謝您。如果您愿意更正一些錯誤或以更好的方式撰寫這段代碼,請隨時這樣做。
import sys
import random
import matplotlib
import matplotlib.pyplot as plt
from PyQt5 import QtCore, QtWidgets
from matplotlib.backends.backend_qt5agg import (
FigureCanvasQTAgg as FigureCanvas,
NavigationToolbar2QT)
from matplotlib.figure import Figure
matplotlib.use('Qt5Agg')
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.resize(500, 500)
button = QtWidgets.QPushButton('Press me')
self.widget_central = QtWidgets.QStackedWidget()
self.widget_central.addWidget(button)
self.setCentralWidget(self.widget_central)
button.clicked.connect(self.screen)
def screen(self):
s = _screen()
self.widget_central.addWidget(s)
self.widget_central.setCurrentWidget(s)
class _screen(QtWidgets.QWidget):
def __init__(self):
super().__init__()
lay = QtWidgets.QHBoxLayout()
groupbox = QtWidgets.QGroupBox()
lay_2 = QtWidgets.QVBoxLayout()
splitter = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
self.slider = QtWidgets.QSlider()
self.slider.setFocusPolicy(QtCore.Qt.NoFocus)
self.slider.setGeometry(30, 40, 200, 30)
self.slider.setRange(0, 100)
self.slider.setValue(100)
self.slider.setInvertedAppearance(True)
self.slider.setTickPosition(QtWidgets.QSlider.TicksBelow)
self.slider.setTickInterval(1)
x_axis = list(range(10))
y_axis = [random.randint(0, 10) for i in range(10)]
self.area_plot = MplCanvas(self, width=5, height=4, dpi=100)
toolbar = NavigationToolbar2QT(self.area_plot, self)
self.area_plot.figure, self.ax = plt.subplots()
self.ax.plot(x_axis, y_axis)
lay_2.addWidget(toolbar)
lay_2.addWidget(self.area_plot)
groupbox.setLayout(lay_2)
splitter.addWidget(self.slider)
splitter.addWidget(groupbox)
lay.addWidget(splitter)
self.setLayout(lay)
self.slider.valueChanged[int].connect(self.graph_uptade)
def graph_uptade(self, value):
QtWidgets.QApplication.processEvents()
x_axis = list(range(10))
y_axis = [value * random.randint(0, 10) for i in range(10)]
self.ax.cla()
self.ax.plot(x_axis, y_axis, 'r')
self.area_plot.figure.canvas.draw_idle()
class MplCanvas(FigureCanvas):
def __init__(self, parent=None, width=5, height=4, dpi=100):
fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = fig.add_subplot(111)
super(MplCanvas, self).__init__(fig)
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
app.exec_()
有一個 QSlider,其范圍從 0 到 100,每次激活滑塊時,該值都會發送到更新基于 QSlider 值的圖形(matplotlib 圖)的函式。圖形實際上會更新并且程式不會崩潰,但是更改不會立即在主螢屏中可見,要查看新圖,我需要最大化視窗,如果我在最大化時再次更新圖形,我將不得不最小化視窗以查看更新版本等。
我嘗試使用 QApplication.ProcessEvents()、plt.cla() plt.plot() plt.draw()、aldo plt.draw_idle() 和其他一些東西,但無濟于事。在這方面似乎沒有什么對我有用。
如果你能幫助我,我將不勝感激。
uj5u.com熱心網友回復:
您的問題是您使用 matplotlib.pyplot ( plt.)定義了子圖。
self.area_plot.figure, self.ax = plt.subplots() <--這里
如果您在定義的圖形上注冊子圖(并稍微清理代碼),它應該按預期作業:
import sys
import random
import matplotlib
import matplotlib.pyplot as plt
from PyQt5 import QtCore, QtWidgets
from matplotlib.backends.backend_qt5agg import (
FigureCanvasQTAgg as FigureCanvas,
NavigationToolbar2QT)
from matplotlib.figure import Figure
matplotlib.use('Qt5Agg')
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.resize(500, 500)
button = QtWidgets.QPushButton('Press me')
self.widget_central = QtWidgets.QStackedWidget()
self.widget_central.addWidget(button)
self.setCentralWidget(self.widget_central)
button.clicked.connect(self.screen)
def screen(self):
s = _screen()
self.widget_central.addWidget(s)
self.widget_central.setCurrentWidget(s)
class _screen(QtWidgets.QWidget):
def __init__(self):
super().__init__()
lay = QtWidgets.QHBoxLayout()
groupbox = QtWidgets.QGroupBox()
lay_2 = QtWidgets.QVBoxLayout()
splitter = QtWidgets.QSplitter(QtCore.Qt.Horizontal)
self.slider = QtWidgets.QSlider()
self.slider.setFocusPolicy(QtCore.Qt.NoFocus)
self.slider.setGeometry(30, 40, 200, 30)
self.slider.setRange(0, 100)
self.slider.setValue(100)
self.slider.setInvertedAppearance(True)
self.slider.setTickPosition(QtWidgets.QSlider.TicksBelow)
self.slider.setTickInterval(1)
x_axis = list(range(10))
y_axis = [random.randint(0, 10) for i in range(10)]
self.area_plot = MplCanvas(self, width=5, height=4, dpi=100)
toolbar = NavigationToolbar2QT(self.area_plot, self)
self.area_plot.figure
self.area_plot.figure.clf() #remove the initial axis labels
self.ax = self.area_plot.figure.add_subplot(111) #add subplot, retrieve axis object
self.ax.plot(x_axis, y_axis)
lay_2.addWidget(toolbar)
lay_2.addWidget(self.area_plot)
groupbox.setLayout(lay_2)
splitter.addWidget(self.slider)
splitter.addWidget(groupbox)
lay.addWidget(splitter)
self.setLayout(lay)
self.slider.valueChanged[int].connect(self.graph_uptade)
def graph_uptade(self, value):
QtWidgets.QApplication.processEvents()
x_axis = list(range(10))
y_axis = [value * random.randint(0, 10) for i in range(10)]
self.ax.cla()
self.ax.plot(x_axis, y_axis, 'r')
self.area_plot.figure.canvas.draw_idle()
class MplCanvas(FigureCanvas):
def __init__(self, parent=None, width=5, height=4, dpi=100):
fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = fig.add_subplot(111)
super(MplCanvas, self).__init__(fig)
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
app.exec_()
uj5u.com熱心網友回復:
您正在用 覆寫圖形subplots(),如果要更新軸,則可以僅使用當前圖形的軸。
改變這一行:
self.area_plot.figure, self.ax = plt.subplots()
對此:
self.ax = self.area_plot.figure.axes[0]
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/394389.html
