It has been claimed that "fig.canvas.draw() is the canonical way to trigger a draw", replacing fig.draw(fig.canvas.get_renderer()). But on the macosx backend, this seems not to work.
Traceback (most recent call last):
File "mpl_issue.py", line 7, in <module>print(legend.get_window_extent())
File "/Users/mwaskom/miniconda3/lib/python3.7/site-packages/matplotlib/legend.py", line 897, in get_window_extentreturnself._legend_box.get_window_extent(renderer=renderer)
File "/Users/mwaskom/miniconda3/lib/python3.7/site-packages/matplotlib/offsetbox.py", line 346, in get_window_extent
w, h, xd, yd, offsets =self.get_extent_offsets(renderer)
File "/Users/mwaskom/miniconda3/lib/python3.7/site-packages/matplotlib/offsetbox.py", line 462, in get_extent_offsets
dpicor = renderer.points_to_pixels(1.)
AttributeError: 'NoneType' object has no attribute 'points_to_pixels'
Expected outcome
On the qt5agg backend, or when uncommenting the (deprecated?) f.draw(f.canvas.get_renderer()) line, the code runs and prints the extent of the legend.
. I think the fix is to add a call to self._draw() before the self.draw_idle() in L50.
I suspect some of this complexity is left from the previous version of the OSX backend which did the rendering via osx-native methods (rather than pushing Agg output into the GUI like it does now (and like the rest of the GUI backends do)) which meant we could not get access to the renderer except when we were handed it by the OSX event loop.
If you look at fig.stale (which comes from Artist so every object in the tree has this state). That state tracks if the artist (or any of its children) have changed from the last time it has rendered. It get initialized to False should should mostly solve the problem you are having.
Activity
Revert change to forced draw command
Revert change to forced draw command (#2408)
tacaswell commented on Dec 30, 2020
The issues appears to be that draw defers to draw_idle with the OSX backend
matplotlib/lib/matplotlib/backends/backend_macosx.py
Lines 48 to 51 in f2c5b37
I suspect some of this complexity is left from the previous version of the OSX backend which did the rendering via osx-native methods (rather than pushing Agg output into the GUI like it does now (and like the rest of the GUI backends do)) which meant we could not get access to the renderer except when we were handed it by the OSX event loop.
mwaskom commented on Dec 30, 2020
Is there a good way to programmatically check that the draw actually happened? i.e so something like
could be used for backwards compatibility.
tacaswell commented on Dec 30, 2020
If you look at fig.stale (which comes from Artist so every object in the tree has this state). That state tracks if the artist (or any of its children) have changed from the last time it has rendered. It get initialized to False should should mostly solve the problem you are having.
Abstract logic of forcing figure draw with matplotlib backcompat
Abstract logic of forcing figure draw with matplotlib backcompat (#2426)
Seaborn original (#1)
Abstract logic of forcing figure draw with matplotlib backcompat (#2426)