我试图在matplotlib中,在一个使用wxPython的“生产”应用程序中实时绘制数据。为了这个目的,我一直在使用Chaco,但是我试图在将来避免使用Chaco,其中一个原因是,由于它没有很好的文档记录,所以当我想将哪怕是最小的特性添加到我的绘图中时,我常常要花很长时间阅读Chaco源代码。Chaco战胜matplotlib的一个方面是在速度上,所以我正在探索从matplotlib获得可接受性能的方法。在
我在matplotlib中看到了一种广泛用于快速绘图的技术,就是将要经常更新的绘图元素的animated
设置为True
,然后只绘制一次背景(轴、刻度线等),然后使用canvas.copy_from_bbox()
方法保存背景。然后,当绘制一个新的foreground
(绘图轨迹等)时,使用canvas.restore_region()
将预渲染的背景复制到屏幕上,然后用axis.draw_artist()
和canvas.blit()
将其绘制到屏幕上。在
我写了一个相当简单的例子,在wxPython帧中嵌入一个FigureCanvasWxAgg,并尝试以45 FPS的速度显示一个随机数据。当程序以默认的帧大小运行时(在我的源代码中是硬编码的),它在我的机器上达到每秒13-14帧。当我最大化窗口时,刷新速度下降到5.5 FPS左右。我认为这对我的应用程序来说不够快,尤其是当我开始添加要实时呈现的附加元素时。在
我的代码发布在这里:basic_fastplot.py
我想知道是否可以加快速度,所以我分析了代码,发现到目前为止,最大的处理时间消耗者是第99行和第109行对canvas.blit()
的调用。我进一步研究了一下,插入matplotlib代码本身,发现大部分时间都花在对MemoryDC.SelectObject()
的特定调用中。在周围的代码中有几个对SelectObject
的调用,但是只有下面标记的一个调用花费了相当多的时间。在
从matplotlib源,后端_wxagg.py公司名称:
class FigureCanvasWxAgg(FigureCanvasAgg, FigureCanvasWx):
# ...
def blit(self, bbox=None):
"""
Transfer the region of the agg buffer defined by bbox to the display.
If bbox is None, the entire buffer is transferred.
"""
if bbox is None:
self.bitmap = _convert_agg_to_wx_bitmap(self.get_renderer(), None)
self.gui_repaint()
return
l, b, w, h = bbox.bounds
r = l + w
t = b + h
x = int(l)
y = int(self.bitmap.GetHeight() - t)
srcBmp = _convert_agg_to_wx_bitmap(self.get_renderer(), None)
srcDC = wx.MemoryDC()
srcDC.SelectObject(srcBmp) # <<<< Most time is spent here, 30milliseconds or more!
destDC = wx.MemoryDC()
destDC.SelectObject(self.bitmap)
destDC.BeginDrawing()
destDC.Blit(x, y, int(w), int(h), srcDC, x, y)
destDC.EndDrawing()
destDC.SelectObject(wx.NullBitmap)
srcDC.SelectObject(wx.NullBitmap)
self.gui_repaint()
我的问题:
目前没有回答
相关问题 更多 >
编程相关推荐