Matplotlib tkagg 后端性能

Matplotlib tkagg backend performance

我有一个可以绘制大量数据的 tkinter 应用程序,当 canvas.

上有大量数据时,我注意到平移和缩放性能不佳

查看 tkagg_backend(如 this 和其他几个问题所建议的),函数和文档表明 canvas 只应在用户空闲时重绘。然而,根据当前和以前的经验,canvas 一直在 zoom/pan 中更新(重绘)。因此,我正在查看所涉及的具体功能,并对此有疑问。

dynamic_update函数:

def dynamic_update(self):
    'update drawing area only if idle'
    # legacy method; new method is canvas.draw_idle
    self.canvas.draw_idle()

canvas.draw_idle() 函数:

def draw_idle(self):
    'update drawing area only if idle'
    if self._idle is False:
        return

    self._idle = False

    def idle_draw(*args):
        try:
            self.draw()
        finally:
            self._idle = True

    self._idle_callback = self._tkcanvas.after_idle(idle_draw)

._idle参数在后台初始化为True。这一点是我卡住的地方,因为我无法理解 ._idle 是如何链接到鼠标 activity (我假设是这样,如果错误请纠正我)。

有趣的是,canvas 通过注释 self.canvas.draw_idle() 行(松开鼠标按钮后重新绘制)表现得像我期望的那样,因此不会调用整个 draw_idle 函数.

因此,我的问题是 _idle 是如何设置的,或者为什么当我不是 idle 时它会重绘我的整个 canvas?

当提到 "being idle" 时,它不是指用户或他的鼠标 activity,而是指 GUI 主循环。 canvas 只应在主循环当前不忙时重绘。这里当然self._idle只是指GUI的matplotlib部分,draw_idle里面的这个结构应该做的是防止canvas在绘制的时候被绘制。

平移或缩放时很容易发生这种情况。鼠标移动到新位置,导致重新绘制。当这次重绘发生时,鼠标已经移动得更远并导致了下一次重绘。在那个时间点,第一次重绘可能还没有完成,因此它会排队。依此类推,以至于在某些时候 GUI 可能变得无响应。为防止这种情况,新的绘制仅在前一个绘制完成后才初始化,并且此行为由 self._idle 是真还是假来控制。