Matplotlib与PyQt - axes.clear()非常慢

时间:2012-12-26 13:55:48

标签: python charts qt4 matplotlib pyqt

我只想在我的节目上绘制图表。我需要使用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秒。这是正常的吗?

1 个答案:

答案 0 :(得分:0)

我知道这是一个相当古老的问题,但是对于所有正在看这个问题的人(像我一样)并且仍在寻找解决方案:

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 ,但在发布之前发布的链接中有以下内容:

  

事实证明,fig.canvas.blit(ax.bbox)是一个坏主意,因为它像疯了一样泄漏内存。您应该使用的是fig.canvas.update(),它同样快但不会泄漏内存。

我还检查了matplotlib.animation模块,但我有一些触发重绘的按钮(就像问题中的问题一样),我无法找到如何在我的特定情况下使用动画。