简体   繁体   English

Matplotlib tkagg后端性能

[英]Matplotlib tkagg backend performance

I have a tkinter application that can plot a large number of data, where I have noticed poor pan and zoom performance when there is a large number of data on the canvas. 我有一个可以绘制大量数据的tkinter应用程序,当画布上有大量数据时,我注意到平移和缩放性能不佳。

Looking into the tkagg_backend (as suggested by this and several other questions), the function and documentation suggests that the canvas should only be redrawn once the user is idle. 查看tkagg_backend( 由此和其他几个问题所建议),函数和文档表明只有在用户空闲时才应重绘画布。 However, from current and previous experience the canvas has always been updating(redrawing) mid zoom/pan. 但是,从当前和以前的经验来看,画布一直在更新(重绘)mid zoom / pan。 Therefore, I was looking at the specific functions that are involved and have a question regarding that. 因此,我正在研究所涉及的具体功能,并对此提出疑问。

The dynamic_update function: dynamic_update函数:

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

The canvas.draw_idle() function: 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)

The ._idle parameter is initialized as True in the backend. ._idle参数在后端初始化为True This point is where I got stuck as I am unable to understand how ._idle is linked to mouse activity (I assume that it is, please correct me if that's wrong). 这一点是我陷入困境的地方,因为我无法理解._idle是如何与鼠标活动相关联的(我假设它是,如果那是错的,请纠正我)。

Interestingly enough, the canvas behaves like I would expect by commenting the self.canvas.draw_idle() line (redrawing once the mouse button is unpressed), and thus not calling the entire draw_idle function. 有趣的是,画布的行为就像我期望的那样,通过注释self.canvas.draw_idle()行(一旦鼠标按钮被按下时重绘),从而不调用整个draw_idle函数。

Therefore, my question is how is _idle set or why does it redraw my entire canvas when I am not idle ? 因此,我的问题是如何设置_idle或为什么在我不idle时重绘整个画布?

When refering to "being idle" it is not the user or his mouse activity that is meant, but rather the GUI mainloop. 当引用“空闲”时,它不是用户或他的鼠标活动,而是GUI主循环。 The canvas should only be redrawn if the mainloop is not currently busy. 如果主循环当前不忙,则只应重绘画布。 Here, of course self._idle only refers to the matplotlib part of the GUI and what this structure inside draw_idle is supposed to do is to prevent the canvas from being drawn while it is being drawn. 这里,当然self._idle只引用GUI的matplotlib部分,而draw_idle这个结构应该做的是防止画布在绘制时被绘制。

This could easily happen when panning or zooming. 平移或缩放时很容易发生这种情况。 The mouse moves to a new location, causing a readraw. 鼠标移动到新位置,导致重新绘制。 While this redraw is happening, the mouse has already moved further and caused the next redraw. 当重绘正在进行时,鼠标已经进一步移动并导致下一次重绘。 At that point in time the first redraw may not yet have finished, such that it would queue up. 在那个时间点,第一次重绘可能尚未完成,因此它将排队。 And so forth, such that at some point the GUI might become unresponsive. 等等,这样在某些时候GUI可能会变得没有响应。 To prevent that, a new draw is only initialized once the previous one has finished and this behaviour is steered by self._idle being true or false. 为了防止这种情况,只有在前一个绘制完成后才会初始化新绘制,并且self._idle为true或false引导此行为。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM