简体   繁体   中英

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.

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 ?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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