plotting/wxPython为什么调用MemoryDC.SelectObject内存()慢?

2024-05-16 04:34:44 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在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()

我的问题:

  • SelectObject()会做什么花这么长时间?我有点假设它只是设置指针等,而不是做太多的复制或计算。在
  • 有没有什么办法可以让我加快速度(全屏大概10帧/秒)?在

Tags: the代码selfnone绘图matplotlibis绘制