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.