带有 PyQt 的 Matplotlib - axes.clear() 非常慢
Posted
技术标签:
【中文标题】带有 PyQt 的 Matplotlib - axes.clear() 非常慢【英文标题】:Matplotlib with PyQt - axes.clear() is very slow 【发布时间】:2012-12-12 01:42:17 【问题描述】:我只想在我的程序上绘制一个图表。我需要多次使用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 秒。正常吗?
【问题讨论】:
当你清除它时,你在轴上绘制了多少东西? 我只是绘制了一些简单的折线图。当用户单击表格上的项目时,图表将更新。用户需要一直点击表格。 你不需要清除整个轴,但通常更新图表的数据就足够了。 我同意@DavidZwicker,您可能应该通过更新现有行来做到这一点,但仍然觉得这是一个奇怪的问题。axes.clear()
真的应该是self.axes.clear()
吗?如果我进行此更改(并假设一个最小接口),refresh
运行时没有可描述的延迟。您能否发布一个显示此显示的最小独立示例?
【参考方案1】:
我知道这是一个相当古老的问题,但对于所有正在查看此问题的人(如我)并仍在寻找解决方案:
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
模块,但我有一些按钮触发重绘(就像问题中所问的那样),我无法找到在我的具体情况下如何使用动画。
【讨论】:
以上是关于带有 PyQt 的 Matplotlib - axes.clear() 非常慢的主要内容,如果未能解决你的问题,请参考以下文章
带有 PyQt 的 Matplotlib - axes.clear() 非常慢