首页 > 解决方案 > PySide2 更新图表

问题描述

很长一段时间以来,我一直在以下问题上撞墙,需要一些新的眼睛来帮助我。

在 Qt Designer 中,我创建了一个带有 QComboBox(用于选择功能)、一个 QPushButton(用于指示功能的绘图)和一个 QWidget(绘图区域,称为 mywidget)的选项卡。整个代码很大程度上受到 SO 上的各种代码的启发。

在 main.py 中,我将 QPushButton 连接到以下函数(在我的 QtApp 类中定义):

def launchGraph(self):
    df1 = ... #data from a data source
    self.mywidget.figure = Figure()
    self.mywidget.canvas = FigureCanvas(self.mywidget.figure)
    self.mywidget.toolbar = NavigationToolbar(self.mywidget.canvas, self)

    self.mywidget.graphLayout = QtWidgets.QVBoxLayout()
    self.mywidget.graphLayout.addWidget(self.mywidget.canvas)
    self.mywidget.graphLayout.addWidget(self.mywidget.toolbar)
    self.mywidget.setLayout(self.mywidget.graphLayout)

    ax1f1 = self.mywidget.figure.add_subplot(111)
    ax1f1.clear()
    ax1f1.xaxis.set_major_formatter(mdates.DateFormatter('%b%-y'))
    ax1f1.plot(df1['x'], df1['y'], linewidth=1, color='blue')
    ax1f1.set(title='My Little Graph')
    self.mywidget.canvas.draw()

问题是,当我启动窗口时,选择一个功能并单击按钮,会显示正确的图表。如果我更改了功能并单击绘图按钮,则没有任何反应。我确实打印了组合框的功能,它从组合框中打印了正确的最新值,但是图表没有被替换/更新。我还添加了一个测试变量 isgraph 并使用了 self.mywidget.figure.clear() 但也没有成功。canvas.repaint() 也不更新图表。感觉就像我需要使用测试变量来检查图表是否存在,如果是,那么我需要整理 mywidget 的内容。但这对于这个问题似乎过于复杂(?)

有关信息,我导入以下内容:

from gui import main
from PySide2 import QtWidgets, QtCore, QtGui

from matplotlib.figure import Figure
import matplotlib.dates as mdates
from matplotlib.dates import DateFormatter
from matplotlib.backends.backend_qt5agg import (FigureCanvasQTAgg as FigureCanvas, 
                                                NavigationToolbar2QT as NavigationToolbar)

编辑: 这是最小/改编的完整代码:

from gui import main
from PySide2 import QtWidgets, QtCore, QtGui
from matplotlib.figure import Figure
import matplotlib.dates as mdates
from matplotlib.dates import DateFormatter
from matplotlib.backends.backend_qt5agg import (FigureCanvasQTAgg as 
FigureCanvas, NavigationToolbar2QT as NavigationToolbar)

class MyQtApp(main.Ui_MainWindow, QtWidgets.QMainWindow):
    def __init__(self):
        super(MyQtApp, self).__init__()
        self.setupUi(self)

        self.graphBtn.clicked.connect(self.launchGraph)

        self.show()

    def launchGraph(self):
        if self.mycb.currrentText() == 'feature1':
            df1 = ... #data from a data source
        else: (#== feature2)
            df1 = ... #some other data

        self.mywidget.figure = Figure()
        self.mywidget.canvas = FigureCanvas(self.mywidget.figure)
        self.mywidget.toolbar = 
                         NavigationToolbar(self.mywidget.canvas, self)

        self.mywidget.graphLayout = QtWidgets.QVBoxLayout()
        self.mywidget.graphLayout.addWidget(self.mywidget.canvas)
        self.mywidget.graphLayout.addWidget(self.mywidget.toolbar)
        self.mywidget.setLayout(self.mywidget.graphLayout)

        ax = self.mywidget.figure.add_subplot(111)
        ax.clear()
        ax.plot(df1['x'], df1['y'])
        self.mywidget.canvas.draw()

在 Qt Designer(文件 main.ui comnverted into.main.py)中,我放置了: - 一个名为 mycb 的组合框,具有 2 个值:[feature1, feature2] - 一个按钮,名为 graphBtn - 一个简单且空的 QWidget,名为 mywidget

标签: python-3.xmatplotlibqt5pyside2

解决方案


问题很可能是,当您launchGraph在初始运行之后运行时,该函数会在初始运行下创建另一个ax1f1。因此,第一个继续显示并且没有显示错误。

在这种特殊情况下,您希望继续使用初始ax1f1值而不是重新声明另一个。

这样的事情可以解决这个问题:

def launchGraph(self):
    if self.mycb.currrentText() == 'feature1':
        df1 = ['some_data'] #data from a data source
    else: (#== feature2)
        df1 = ['some_other_data'] #some other data
    self.mywidget.figure = Figure()
    self.mywidget.canvas = FigureCanvas(self.mywidget.figure)
    self.mywidget.toolbar = NavigationToolbar(self.mywidget.canvas, self)

    self.mywidget.graphLayout = QtWidgets.QVBoxLayout()
    self.mywidget.graphLayout.addWidget(self.mywidget.canvas)
    self.mywidget.graphLayout.addWidget(self.mywidget.toolbar)
    self.mywidget.setLayout(self.mywidget.graphLayout)

    try:
        self.ax1f1.clear()
    except:
        self.a1f1 = self.mywidget.figure.add_subplot(111)
        self.ax1f1.clear()

    self.ax1f1.xaxis.set_major_formatter(mdates.DateFormatter('%b%-y'))
    self.ax1f1.plot(df1['x'], df1['y'], linewidth=1, color='blue')
    self.ax1f1.set(title='My Little Graph')
    self.mywidget.canvas.draw()

推荐阅读