在 pyqt5 小部件中更新 matplotlib
Posted
技术标签:
【中文标题】在 pyqt5 小部件中更新 matplotlib【英文标题】:Updating matplotlib in pyqt5 widget 【发布时间】:2021-02-18 20:49:53 【问题描述】:我在 qt 设计器中创建了一个 UI 并使用 UIC 加载它。我对 UI 进行了更新,所以我不想将 UI 转换为 python。我正在使用以下帖子嵌入我的 PLT: Embed a matplotlib plot in a pyqt5 gui
但是,我尝试更新图表,但使用以下不同方法均失败:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>728</width>
<height>429</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QWidget" name="graphWidget" native="true">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>551</width>
<height>351</height>
</rect>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Button">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Light">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Midlight">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Dark">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>127</red>
<green>127</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
<colorrole role="Mid">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>170</red>
<green>170</green>
<blue>170</blue>
</color>
</brush>
</colorrole>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="BrightText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Shadow">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="AlternateBase">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="ToolTipBase">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>220</blue>
</color>
</brush>
</colorrole>
<colorrole role="ToolTipText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="PlaceholderText">
<brush brushstyle="SolidPattern">
<color alpha="128">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Button">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Light">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Midlight">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Dark">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>127</red>
<green>127</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
<colorrole role="Mid">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>170</red>
<green>170</green>
<blue>170</blue>
</color>
</brush>
</colorrole>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="BrightText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Shadow">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="AlternateBase">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="ToolTipBase">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>220</blue>
</color>
</brush>
</colorrole>
<colorrole role="ToolTipText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="PlaceholderText">
<brush brushstyle="SolidPattern">
<color alpha="128">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="WindowText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>127</red>
<green>127</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
<colorrole role="Button">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Light">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Midlight">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Dark">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>127</red>
<green>127</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
<colorrole role="Mid">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>170</red>
<green>170</green>
<blue>170</blue>
</color>
</brush>
</colorrole>
<colorrole role="Text">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>127</red>
<green>127</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
<colorrole role="BrightText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="ButtonText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>127</red>
<green>127</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Shadow">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="AlternateBase">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="ToolTipBase">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>220</blue>
</color>
</brush>
</colorrole>
<colorrole role="ToolTipText">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="PlaceholderText">
<brush brushstyle="SolidPattern">
<color alpha="128">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
</widget>
<widget class="QPushButton" name="start">
<property name="geometry">
<rect>
<x>590</x>
<y>30</y>
<width>91</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>Start</string>
</property>
</widget>
<widget class="QPushButton" name="restart">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>590</x>
<y>100</y>
<width>91</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>Restart</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
<widget class="QLabel" name="label_7">
<property name="geometry">
<rect>
<x>730</x>
<y>130</y>
<width>171</width>
<height>71</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
<widget class="QPushButton" name="intervene">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>590</x>
<y>170</y>
<width>91</width>
<height>41</height>
</rect>
</property>
<property name="text">
<string>Intervene</string>
</property>
<property name="checkable">
<bool>false</bool>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>728</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
from PyQt5 import QtCore, QtWidgets, uic
import pyqtgraph as pg
import sys # We need sys so that we can pass argv to QApplication
import time
import matplotlib
import matplotlib.pylab as plt
from matplotlib.backends.backend_qt5agg import FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
import numpy as np
from scipy.spatial import Voronoi, voronoi_plot_2d
matplotlib.use('QT5Agg')
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
# Load the UI
uic.loadUi('src\Main.ui', self)
# Runs functions on button press
self.start.clicked.connect(self.startfcn)
# add toolbar
# self.addToolBar(QtCore.Qt.BottomToolBarArea, NavigationToolbar(self.canvas, self))
# This function is run when the start button is pushed
def startfcn(self):
sd = 20
# rng(sd)
numIterations = 1000
samplingPeriod = 10
xrange = 10 # region size
yrange = 5
n = 20 # number of robots (changing the number of robots is interesting)
dt = 1
maxSpeed = 8
# Draw graph
points = np.random.rand(10, 2) # random points for Voronoi
vor = Voronoi(points) # Create Voronoi object
fig = voronoi_plot_2d(vor) # Make vor object into a plot object
canvas = FigureCanvas(fig) # create a mpl canvas obj
lay = QtWidgets.QVBoxLayout(self.graphWidget) # create layout in graph widget
lay.setContentsMargins(0, 0, 0, 0)
lay.addWidget(canvas) # add canvas obj to layout
# all of these are attempts to update the graph
canvas.draw()
self.graphWidget.update()
self.graphWidget.show()
QtWidgets.QApplication.processEvents()
def main():
app = QtWidgets.QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
当按下开始按钮时,它应该显示一个新的随机 voronoi 图,但它没有。
每次按下开始按钮时我都需要它来更新 graphWidget。
【问题讨论】:
我不知道为什么 UI 这么长,但它基本上是主窗口和一个名为 graphWidget 的 qwidget,然后是一些按钮 再次按下按钮应该会显示一个新的随机 voronoi 图,这不起作用 【参考方案1】:如果您要更改 Figure
,那么您必须创建一个新的画布,这样您就必须销毁之前的画布:
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.canvas = None
uic.loadUi("Main.ui", self)
self.canvas_layout = QtWidgets.QVBoxLayout(self.graphWidget)
self.canvas_layout.setContentsMargins(0, 0, 0, 0)
self.start.clicked.connect(self.startfcn)
# add toolbar
# self.addToolBar(QtCore.Qt.BottomToolBarArea, NavigationToolbar(self.canvas, self))
# This function is run when the start button is pushed
def startfcn(self):
# Draw graph
points = np.random.rand(10, 2) # random points for Voronoi
vor = Voronoi(points) # Create Voronoi object
fig = voronoi_plot_2d(vor) # Make vor object into a plot object
if self.canvas is not None:
self.canvas.deleteLater()
self.canvas = FigureCanvas(fig)
self.canvas_layout.addWidget(self.canvas)
另一个更好的选择是通过“ax”参数将坐标轴传递给voronoi_plot_2d()
方法:
import sys
from PyQt5 import QtCore, QtWidgets, uic
import matplotlib
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt5agg import FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
import numpy as np
from scipy.spatial import Voronoi, voronoi_plot_2d
matplotlib.use("QT5Agg")
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.canvas = FigureCanvas(Figure())
uic.loadUi("Main.ui", self)
lay = QtWidgets.QVBoxLayout(self.graphWidget)
lay.setContentsMargins(0, 0, 0, 0)
lay.addWidget(self.canvas)
self.start.clicked.connect(self.startfcn)
self.ax = None
# add toolbar
# self.addToolBar(QtCore.Qt.BottomToolBarArea, NavigationToolbar(self.canvas, self))
# This function is run when the start button is pushed
def startfcn(self):
if self.ax is None:
self.ax = self.canvas.figure.subplots()
# Draw graph
points = np.random.rand(10, 2) # random points for Voronoi
vor = Voronoi(points) # Create Voronoi object
self.ax.clear()
voronoi_plot_2d(vor, ax=self.ax) # Make vor object into a plot object
self.canvas.draw()
def main():
app = QtWidgets.QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
【讨论】:
第一种方法会给你一个警告,警告你打开了太多的地块。我实现了类似第二个的东西。此外,我能找到的唯一有用的 MPL 文档:matplotlib.org/3.1.1/gallery/user_interfaces/… @bobthebuilder 什么工具给你这个警告? 使用pycharm,终端输出警告以上是关于在 pyqt5 小部件中更新 matplotlib的主要内容,如果未能解决你的问题,请参考以下文章
从 Matplotlib 图中提取信息并将其显示在 PyQt5 GUI 中