| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
|
At first blush, this looks like a nice simplification. Ping me to come back and look again as it progresses. One possible further simplification: Maybe include a default stale_callback method that is a no-op, rather than requiring if self.stale_callback is not None everywhere it is called? That seems like the kind of thing that could be forgotten down the road. |
Sorry, something went wrong.
Yes it is. "draw_idle" is a bit of a misnomer; "invalidate" may be better. The purpose of draw_idle is to let the canvas know that it is stale. How the canvas responds to that is up to the backend. Typically, a GUI backend will indeed schedule a redraw when the event loop is idle, but I could imagine that in specific backends draw_idle does something else (e.g. set a flag or something). Not sure if this is what you were asking, but anyway I hope it helps. |
Sorry, something went wrong.
|
@mdehoon I disagree about the purpose of draw_idle, it is to instruct the canvas that it should redraw at the next opportunity (vs draw which is telling the canvas to re-render right now). The details of how this is implemented is up to the backends (and in the case of macosx you deal with this by having an 'invalid' flag which the draw loop knows to mean it should re-draw on this cycle through), but other wise the canvas objects are (publicly) stateless and the implementation in backend bases to pass draw_idle through to draw (which really only matters for agg in terms of the backends we ship) is perfectly correct. Trying to implement this highlighted a design choice that did not get articulated in my conversation with @mdehoon is mpl's idea of where the stale/invalid state should live is in scene graph tree or in the canvas. As I have implemented it, it lives in the scene graph, as @mdehoon wants it (and as it is explicitly implemented in macosx, explicitly as part of draw_idle in some backends, and deep in the guts of Qt currently) the state lives on the canvas side. I think the arguments for doing this on the scene graph side are:
Although I admittedly have trouble coming up with a good use case, but forcing users into our idea of what the draw cadence should be seems wrong (but on the other hand, just turning interactive mode off seems to be the cut-out). |
Sorry, something went wrong.
|
@tacaswell Just for clarification,
There is no explicit 'invalid' flag in the macosx backend; currently draw_idle in the macosx backend simply calls canvas.invalidate(), which (in the C code) calls Apple's API function to schedule a redraw. There may be some 'invalid' flag hidden deep in Apple's libraries, but there is no explicit 'invalid' flag within matplotlib. In this sense it is similar to Qt. Tkagg is different as it draws to _tkphoto, which then needs to be blitted explicitly. |
Sorry, something went wrong.
This is the result of a phone discussion with @medhoon The idea is to not rely on pyplot knowing to check if the figure needs to be re-drawn, but just have the Figure object directly kick the canvas to draw_idle. This does not currently work with nbagg due to the first draw_idle being fired before it is finished building it's self. There maybe similar race conditions in the other backends.
| Back | FazBrowse Home | New Git URL |
Built on top of #4738
@mdehoon
When I went to implement this I grew confused as to where the canvas knowing it was stale would fit in. Isn't the call to draw_idle the message to the canvas that it is stale?
There were also some issues with the first draw_idle going out before all of the objects had finished building them selves adding stale to the canvas in the naive way because callbacks in python get executed synchronously.
I did re-work how the stale state gets propagated and (I think) greatly simplified it by adding a dedicated callback.
As-is this has an issue with __init__ order of operations with the nbagg backend which I don't have time to debug tonight.
I am worried about how this method will interact with nbagg which has a js side event loop running in the browser and then call backs listening to comms on the python side. By hooking into the IPython callbacks we get to leverage their understanding of how to manage things.