| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
|
I am 👎 on this. Every artist has a draw method that requires a renderer to be passed in and I am skeptical of making the figure draw special. We already have savefig on the Figure and , draw and draw_idle on the Canvas which is indisputably confusing, but I do not think that re-purposing Figure.draw to also be a user-facing will improve things (and might make it worse as there will be one more way that "works"). |
Sorry, something went wrong.
|
What is the user-facing way to force a draw on a figure if not Figure.draw()? Maybe I'm just confused, but thats usually how I trigger a draw, except I have to do a song and dance to get the renderer. |
Sorry, something went wrong.
|
fig.canvas.draw() |
Sorry, something went wrong.
|
I think the interplay between a figure and its canvas is pretty obscure to most people, including me apparently. I still think a discoverable way to trigger a draw is preferable, but don't feel super strongly about it. |
Sorry, something went wrong.
|
Actually I'll re-open. We do need to tell users to trigger draws, and having to send them to something that is undocumented is not great. I think that trumps aesthetics as to whether figure is a special artist or not. As for other artists, I'd be fine if we wanted them to get their canvas and use that as a default in all these routines... |
Sorry, something went wrong.
|
Without having looked into the details and without claiming to understand the internal mechanics: draw() feels like a closed operation that does not need parametrization. Are there cases in which we need to pass different renderers? |
Sorry, something went wrong.
|
I believe that a problem is that fig.canvas.draw clears the canvas first, whereas artist.draw (including figure.draw doesn't (it can't, of course: its semantics are to draw just itself onto a canvas which may already have other artists drawn). |
Sorry, something went wrong.
|
Hmm, we have fig.draw() which just draws the figure onto the canvas without erasing what was there before. We have fig.canvas.draw which erases the canvas first, and we have plt.draw the uses of which I do not understand. What I am suggesting here is to change fig.draw to work without a renderer. If that just means calling down to fig.canvas.draw I am fine with that. If we want pyplot.draw to instead call fig.canvas.draw I'd be fine with that. I agree this is all confusing, but my confusion is that I don't understand all the other needs to call draw, or ion or the other weird ways we have of triggering things. |
Sorry, something went wrong.
|
There's (i) fig.canvas.draw and (ii) fig.canvas.draw_idle for drawing the whole canvas. The latter defers the draw to when control is back to the GUI event loop, and it prevents multiple draws piling up during that time. (ii) should call (i). |
Sorry, something went wrong.
|
Thanks, that all sounds right. Unfortunately plt.draw() and fig.canvas.draw_idle() do not trigger a draw mid-script, so they are not useful for cases where you need to force a draw to determine where something is on the canvas. i.e. import matplotlib.pyplot as plt fig, ax = plt.subplots(constrained_layout=True) renderer = fig.canvas.get_renderer() print(ax.get_tightbbox(renderer)) # gives Bbox(x0=96.18055555555554, y0=58.15555555555555, x1=1174.125, y1=855.8) plt.draw() print(ax.get_tightbbox(renderer)) # gives same fig.canvas.draw() print(ax.get_tightbbox(renderer)) # actually repositions things: Bbox(x0=8.334000000000003, y0=8.334000000000003, x1=1271.666, y1=951.666) and only the last fig.canvas.draw() actually triggers a draw. I guess this is because the window hasn't been opened yet so the QTimer is not acting on anything, so draw_idle doesn't do anything (the _draw_idle this is supposed to queue up never gets called if the window never opens). I will still maintain that it is unintuitive that just to get the proper position of elements on the canvas we have to reach down and force a draw on the canvas |
Sorry, something went wrong.
Mid-script you have not given the Qt event loop a chance to run (see https://matplotlib.org/stable/users/interactive_guide.html#scripts-and-functions).
yes. To make matters worse there is also Axes.draw_artist and Figure.draw_arist (which redraws a child using a cached renderer and Axes.draw_in_frame (which redraws a sub-selection of the Axes children) and the print_XYZ methods that we use in savefig. I agree it is confusing that almost everything is named draw despite doing different things, but I still think adding a special case on Figure.draw will only make it worse. In 3.4 we made sure that fig.canvas.draw also does the right thing for non-interactive backends: #18408 I think what we should do instead is to promote matplotlib/lib/matplotlib/backend_bases.py Lines 1587 to 1590 in c81f58d |
Sorry, something went wrong.
|
I think that would be great plus or minus the name. |
Sorry, something went wrong.
|
Fig.no_output_draw doesn't seem so bad to me, or draw_no_output. |
Sorry, something went wrong.
As a frequent user of constrained_layout, I have been saving figures to a BytesIO object to trigger a draw (since it works even for a non interactive backend like pgf): with io.BytesIO() as temp_io_buffer:
fig.savefig(temp_io_buffer)so replacing all that with a Fig.no_output_draw does sound like a good idea! |
Sorry, something went wrong.
|
So I think the consensus here is:
"no_output_draw" is a bit miss leading because the "output" of fig.canvas.draw is all side-effects and dependent on the backend. What _no_output_draw is doing is disabling all of the draw_XYZ methods (which need to be added to the list of method names that have draw in them!) so that we run the code in the Arist.draw method but the render methods are no-ops (which is both a performance thing and a "managing state" thing as some thing (e.g. the pdf backend) require a live file handle to write to). I think the name needs to communicate that this:
|
Sorry, something went wrong.
|
I'm just a simple fellow, with minimal knowledge of the backends, but that sounds a lot like drawing with "no output" to the screen or file system. I don't think "no output" conveys nothing happens. |
Sorry, something went wrong.
|
But that's also closed? |
Sorry, something went wrong.
|
Ooops, #19968 replaces that. I was trying a new GitHub workflow, and obviously didn't understand what it was doing! |
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
PR Summary
I'm not sure why we required the renderer to be passed to fig.draw, but suggest we allow it to be a kwarg and default to fig.canvas.get_renderer()
PR Checklist