Skip to main content
 首页 » 编程设计

python之带有 PyQt 的 Matplotlib之axes.clear() 非常慢

2025年05月04日10freeliver54

我只想在我的程序上绘制图表。我需要多次使用 axes.clear() 绘制新图表。

from PyQt4 import QtGui 
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas    
from matplotlib.figure import Figure 
 
class MplCanvas(FigureCanvas): 
 
    def __init__(self): 
        self.fig = Figure() 
        self.axes = self.fig.add_subplot(111) 
 
        # do something... 
        FigureCanvas.__init__(self, self.fig) 
        FigureCanvas.setSizePolicy(self, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) 
        FigureCanvas.updateGeometry(self) 
        # do something... 
 
    def refresh(self): 
        # FIXME: This method is very, very slow!!! 
        self.axes.clear() 
 
        # do something... 

但是它很慢,它会挂起我的程序大约 0.3 秒。正常吗?

请您参考如下方法:

我知道这是一个相当古老的问题,但对于所有正在研究这个问题(比如我)并且仍在寻找解决方案的人来说:

class MplCanvas(FigureCanvas): 
    def __init__(self): 
        #... 
 
        # get a reference to the line you want to plot 
        self.line = self.axes.plot(xdata, ydata) 
 
    def resfresh(self, xdata, ydata): 
        # set the new data on one or more lines 
        self.line.set_data(xdata, ydata) 
 
        # redraw the axis (and re-limit them) 
        axes.relim() 
        axes.autoscale_view() 
 
        # redraw the figure 
        self.fig.canvas.draw() 

我在一个图中将其与多个子图和多个轴一起使用,这已经大大加快了我的处理速度。我无法进一步精简我的代码,因为我的绘图正在调整轴的大小并且标题正在更改。

如果您知道您只想要重新绘制数据以便轴、标题和范围将保持不变,您可以将其进一步剥离:

def refresh(self, xdata, ydata): 
    # "delete" the background contents, this is only repainting an empty 
    # background which will look a little bit differently but I'm 
    # fine with it 
    self.axes.draw_artist(self.axes.patch) 
 
    # set the new data, could be multiple lines too 
    self.line.set_data(xdata, ydata) 
    self.axes.draw_artist(self.line) 
 
    # update figure 
    self.fig.canvas.update() 
    self.fig.canvas.flush_events() 

我从here中获取了很多信息.如果您仍想提高速度,可能有机会使用 blitting 但在之前发布的链接中写着:

As it turns out, fig.canvas.blit(ax.bbox) is a bad idea since it leaks memory like crazy. What you should use instead is fig.canvas.update(), which is equally fast but does not leak memory.

我也在检查 matplotlib.animation 模块,但我有一些按钮触发重绘(就像问题中问的那样),我找不到如何在我的特定中使用动画案例。