我正在用PyQt 6构建一个GUI,其中有一部分是基于matplotlib的图形可视化。
要可视化的图形完全构建在函数内部,这些函数返回一个已经组装好并准备绘制的matplotlib的figure对象-在本例中,是一个不受pyplot
本地管理的matplotlib.figure.Figure
对象(我宁愿不改变这一点)。现在,我努力想知道我该如何(或者即使可能)在同一matplotlib画布中绘制一个图对象,而不删除先前的图对象。
下面是我所拥有的matplotlib小部件的一个最小工作示例。方法“update_figure”用于将第一个图对象绘制到画布上(它已经工作)。然后,方法“add_figure”将用于绘制后续的图对象。在这两个方法中,变量“new_figure”是matplotlib图对象。
# ------------------------------------------------------
# -------------------- mplwidget.py --------------------
# ------------------------------------------------------
from PyQt6.QtWidgets import*
from matplotlib.backends.backend_qtagg import FigureCanvasQTAgg
from matplotlib.figure import Figure
from PyQt6.QtGui import QFont, QFontInfo
import matplotlib.pyplot as plt
import matplotlib
matplotlib.use('Qt5Agg')
class MplWidget(QWidget):
def __init__(self, parent = None):
super(QWidget, self).__init__()
self.canvas = FigureCanvasQTAgg(Figure())
vertical_layout = QVBoxLayout()
vertical_layout.addWidget(self.canvas)
self.canvas.axes = self.canvas.figure.add_subplot(111)
self.canvas.draw()
#Get the default font style from the system and apply to the canvas
self.resetFontStyle()
self.setLayout(vertical_layout)
def update_figure(self, new_figure):
# new_figure is a matplotlib figure object
# Clear the existing figure content
self.canvas.figure.clf()
self.canvas.axes.cla()
# Copy the contents of the new figure onto the canvas
self.canvas.figure = new_figure
# Redraw the canvas
self.canvas.draw()
def add_figure(self, new_figure):
# new_figure is a matplotlib figure object
#This is what I want to implement
我试着看看是否有某种方法可以复制图形对象的全部信息并插入画布的当前轴,但没有成功。
1条答案
按热度按时间r6vfmomb1#
如果有人看到这篇文章,我设计了两种方法来处理这个问题:
1.使用
copy
模块和deepcopy
方法将new_figure
对象复制到self.canvas.figure
中。1.只需擦除
self.canvas.figure.clf()
和self.canvas.axes.cla()
。这出现(直到现在在我的测试中),以允许画布刷新。我最初的问题是,我没有注意到,当我将
new_figure
传递给函数update_figure
,并将其“赋值”给self.canvas.figure
时,我真正做的是使self.canvas.figure
引用相同的matplotlib.figure.Figure对象。然后,当我试图用new_figure
更新画布时,方法self.canvas.figure.clf()
和self.canvas.axes.cla()
作用于由new_figure
引用的同一对象,虚拟地擦除其数据。上面的第一个解决方案有效的原因是因为当深度复制对象时,我们将
self.canvas.figure
与new_figure
分离,然后可以执行.clf()
和.clear()
第二种解决方案是我的首选,因为它不涉及复制对象。我现在不记得为什么了,但我认为简单地调用
self.canvas.draw()
会堆积旧图,我必须首先清除图。但现在我注意到情况并非如此,GUI似乎按预期工作。