Matplotlib tkagg backend performance

醉酒当歌 提交于 2019-12-11 04:46:25

问题


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.

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. However, from current and previous experience the canvas has always been updating(redrawing) mid zoom/pan. Therefore, I was looking at the specific functions that are involved and have a question regarding that.

The dynamic_update function:

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:

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. 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).

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.

Therefore, my question is how is _idle set or why does it redraw my entire canvas when I am not idle?


回答1:


When refering to "being idle" it is not the user or his mouse activity that is meant, but rather the GUI mainloop. 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.

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. 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.



来源:https://stackoverflow.com/questions/44416336/matplotlib-tkagg-backend-performance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!