通过提供一个figure对象更新PyQt6中的matplotlib画布

93ze6v8z  于 2023-10-24  发布在  其他
关注(0)|答案(1)|浏览(158)

我正在用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

我试着看看是否有某种方法可以复制图形对象的全部信息并插入画布的当前轴,但没有成功。

r6vfmomb

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.figurenew_figure分离,然后可以执行.clf().clear()
第二种解决方案是我的首选,因为它不涉及复制对象。我现在不记得为什么了,但我认为简单地调用self.canvas.draw()会堆积旧图,我必须首先清除图。但现在我注意到情况并非如此,GUI似乎按预期工作。

相关问题