You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PyQt5中更新Widget画布以刷新Matplotlib图表?

问题解决:PyQt5中Matplotlib图表点击按钮无法刷新的问题

问题现象

点击按钮会基于10个随机整数生成Matplotlib图表,首次点击可正常显示,但后续点击图表无变化,无法刷新。

问题根源

原代码每次点击按钮时都会新建一个MplCanvas实例和QVBoxLayout,然后重复给self.widget设置布局。Qt中重复设置布局会导致旧的控件和布局未被正确清理,新的canvas无法正常替换显示。正确的做法应该是复用已有的绘图画布,仅更新绘图数据并刷新画布。

修改后的代码

main.py

import sys
import numpy as np
from PyQt5 import uic
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import *
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg

[form_class, QMainWindow] = uic.loadUiType('myuifile.ui')

class MplCanvas(FigureCanvasQTAgg):
    def __init__(self):
        fig = Figure()
        self.axes = fig.add_subplot(111)
        super(MplCanvas, self).__init__(fig)

class Main(form_class, QMainWindow):
    def __init__(self):
        super(Main, self).__init__()
        self.setupUi(self)
        
        # 初始化时就创建画布并添加到widget的布局中
        self.canvas = MplCanvas()
        layout = QtWidgets.QVBoxLayout(self.widget)
        layout.addWidget(self.canvas)
        
        self.pushButton.clicked.connect(self.plot_graph)

    def plot_graph(self):
        x = range(10)
        y = np.random.randn(10)
        
        # 清除旧的绘图内容
        self.canvas.axes.clear()
        # 绘制新的图表
        self.canvas.axes.plot(x, y)
        # 刷新画布
        self.canvas.draw()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    main = Main()
    main.show()
    app.exec_()

myuifile.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
  <class>Form</class>
  <widget class="QWidget" name="Form">
    <property name="geometry">
      <rect>
        <x>0</x>
        <y>0</y>
        <width>496</width>
        <height>404</height>
      </rect>
    </property>
    <property name="windowTitle">
      <string>Form</string>
    </property>
    <layout class="QGridLayout" name="gridLayout">
      <item row="0" column="0">
        <widget class="QPushButton" name="pushButton">
          <property name="font">
            <font>
              <family>Consolas</family>
              <weight>75</weight>
              <bold>true</bold>
            </font>
          </property>
          <property name="text">
            <string>PushButton</string>
          </property>
        </widget>
      </item>
      <item row="0" column="1">
        <spacer name="horizontalSpacer">
          <property name="orientation">
            <enum>Qt::Horizontal</enum>
          </property>
          <property name="sizeHint" stdset="0">
            <size>
              <width>376</width>
              <height>20</height>
            </size>
          </property>
        </spacer>
      </item>
      <item row="1" column="0" colspan="2">
        <widget class="QWidget" name="widget" native="true">
          <property name="font">
            <font>
              <family>Consolas</family>
              <weight>75</weight>
              <bold>true</bold>
            </font>
          </property>
          <property name="autoFillBackground">
            <bool>false</bool>
          </property>
          <property name="styleSheet">
            <string notr="true">background-color: rgb(255, 255, 255);</string>
          </property>
        </widget>
      </item>
    </layout>
  </widget>
  <resources/>
  <connections/>
</ui>

效果说明

修改后,每次点击按钮时:

  • 会先清除画布上的旧图表
  • 绘制新的随机数据图表
  • 立即刷新画布,实现图表的实时更新

应用界面说明:顶部左侧是一个Consolas加粗字体的按钮,右侧为水平占位空间,下方是白色背景的区域用于显示Matplotlib图表。

内容的提问来源于stack exchange,提问作者agile

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 02:24:30