Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
plotting/wxPython-为什么对MemoryDC.SelectObject()的调用很慢?_Python_Wxpython_Plot_Matplotlib_Real Time - Fatal编程技术网

plotting/wxPython-为什么对MemoryDC.SelectObject()的调用很慢?

plotting/wxPython-为什么对MemoryDC.SelectObject()的调用很慢?,python,wxpython,plot,matplotlib,real-time,Python,Wxpython,Plot,Matplotlib,Real Time,我试图在matplotlib中,在使用wxPython的生产应用程序中实时绘制数据。我一直在为此目的使用Chaco,但出于许多原因,我试图在将来避免使用Chaco,其中一个原因是因为它没有很好的文档记录,所以当我想在我的一个绘图中添加哪怕是最小的功能时,我通常都必须花很长时间阅读Chaco源代码。Chaco战胜matplotlib的一个方面是速度,因此我正在探索从matplotlib获得可接受性能的方法 我在matplotlib中看到的一种广泛用于快速绘图的技术是,为希望经常更新的绘图元素设置动

我试图在matplotlib中,在使用wxPython的生产应用程序中实时绘制数据。我一直在为此目的使用Chaco,但出于许多原因,我试图在将来避免使用Chaco,其中一个原因是因为它没有很好的文档记录,所以当我想在我的一个绘图中添加哪怕是最小的功能时,我通常都必须花很长时间阅读Chaco源代码。Chaco战胜matplotlib的一个方面是速度,因此我正在探索从matplotlib获得可接受性能的方法

我在matplotlib中看到的一种广泛用于快速绘图的技术是,为希望经常更新的绘图元素设置动画为True,然后只绘制一次背景轴、记号等,并使用canvas.copy_from_bbox方法保存背景。然后,在绘制新前景(打印轨迹等)时,使用canvas.restore_region将预渲染的背景复制到屏幕上,然后使用axis.draw_artist和canvas.blit将新前景绘制到屏幕上

我编写了一个相当简单的示例,将FigureCanvasWxAgg嵌入到wxPython帧中,并尝试以45 FPS的速度显示随机数据的单个轨迹。当程序以我的源代码中硬编码的默认帧大小运行时,在我的机器上达到每秒13-14帧。当我最大化窗口时,刷新速度下降到5.5 FPS左右。我认为这对于我的应用程序来说还不够快,尤其是当我开始添加额外的实时渲染元素时

我的代码发布在这里:

我想知道这是否可以更快,所以我分析了代码,发现到目前为止,处理时间的最大消耗者是第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 FPS?
我在pyqt中做了一些,这对我很有帮助[SRCBMP有可能做懒惰的评估吗?@ MalRangsOM?你可能在那里。我试过在调试器中通过BLIT代码,发现SRCBMP是WxBuffMeX+WXBITMAP的C++指针的一个SWIG包装器。你知道有什么方法可以根据对象状态来判断WxButMax是否会被懒惰地评估?EED找到一种方法,可以对C++的实现进行选择,继续进行调查。