Skip to content

Commit 7bb5b21

Browse files
committed
MNT: Remove cached renderer from figure
Let the canvas decide whether to cache the renderer or not and request the renderer from the canvas. The canvas can either return a cached version or a new one.
1 parent 02e93e2 commit 7bb5b21

File tree

10 files changed

+21
-40
lines changed

10 files changed

+21
-40
lines changed

doc/api/axes_api.rst

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,6 @@ Drawing
563563
Axes.draw
564564
Axes.draw_artist
565565
Axes.redraw_in_frame
566-
Axes.get_renderer_cache
567566

568567
Axes.get_rasterization_zorder
569568
Axes.set_rasterization_zorder
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
``Axes.get_renderer_cache``
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
The canvas now takes care of the renderer and whether to cache it
5+
or not. The alternative is to call ``axes.figure.canvas.get_renderer()``.

lib/matplotlib/axes/_base.py

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3078,33 +3078,22 @@ def draw(self, renderer):
30783078
def draw_artist(self, a):
30793079
"""
30803080
Efficiently redraw a single artist.
3081-
3082-
This method can only be used after an initial draw of the figure,
3083-
because that creates and caches the renderer needed here.
30843081
"""
3085-
if self.figure._cachedRenderer is None:
3086-
raise AttributeError("draw_artist can only be used after an "
3087-
"initial draw which caches the renderer")
3088-
a.draw(self.figure._cachedRenderer)
3082+
a.draw(self.figure.canvas.get_renderer())
30893083

30903084
def redraw_in_frame(self):
30913085
"""
30923086
Efficiently redraw Axes data, but not axis ticks, labels, etc.
3093-
3094-
This method can only be used after an initial draw which caches the
3095-
renderer.
30963087
"""
3097-
if self.figure._cachedRenderer is None:
3098-
raise AttributeError("redraw_in_frame can only be used after an "
3099-
"initial draw which caches the renderer")
31003088
with ExitStack() as stack:
31013089
for artist in [*self._axis_map.values(),
31023090
self.title, self._left_title, self._right_title]:
31033091
stack.enter_context(artist._cm_set(visible=False))
3104-
self.draw(self.figure._cachedRenderer)
3092+
self.draw(self.figure.canvas.get_renderer())
31053093

3094+
@_api.deprecated("3.6", alternative="Axes.figure.canvas.get_renderer()")
31063095
def get_renderer_cache(self):
3107-
return self.figure._cachedRenderer
3096+
return self.figure.canvas.get_renderer()
31083097

31093098
# Axes rectangle characteristics
31103099

lib/matplotlib/backend_bases.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1535,8 +1535,7 @@ def _mouse_handler(event):
15351535

15361536
def _get_renderer(figure, print_method=None):
15371537
"""
1538-
Get the renderer that would be used to save a `.Figure`, and cache it on
1539-
the figure.
1538+
Get the renderer that would be used to save a `.Figure`.
15401539
15411540
If you need a renderer without any active draw methods use
15421541
renderer._draw_disabled to temporary patch them out at your call site.
@@ -1559,7 +1558,7 @@ def _draw(renderer): raise Done(renderer)
15591558
try:
15601559
print_method(io.BytesIO())
15611560
except Done as exc:
1562-
renderer, = figure._cachedRenderer, = exc.args
1561+
renderer, = exc.args
15631562
return renderer
15641563
else:
15651564
raise RuntimeError(f"{print_method} did not call Figure.draw, so "

lib/matplotlib/backends/backend_cairo.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,9 @@ def _renderer(self):
422422
self._cached_renderer = RendererCairo(self.figure.dpi)
423423
return self._cached_renderer
424424

425+
def get_renderer(self):
426+
return self._renderer
427+
425428
def copy_from_bbox(self, bbox):
426429
surface = self._renderer.gc.ctx.get_target()
427430
if not isinstance(surface, cairo.ImageSurface):

lib/matplotlib/backends/backend_wx.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,7 @@ def gui_repaint(self, drawDC=None):
620620
# DC (see GraphicsContextWx._cache).
621621
bmp = (self.bitmap.ConvertToImage().ConvertToBitmap()
622622
if wx.Platform == '__WXMSW__'
623-
and isinstance(self.figure._cachedRenderer, RendererWx)
623+
and isinstance(self.figure.canvas.get_renderer(), RendererWx)
624624
else self.bitmap)
625625
drawDC.DrawBitmap(bmp, 0, 0)
626626
if self._rubberband_rect is not None:

lib/matplotlib/figure.py

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2191,7 +2191,6 @@ def axes(self):
21912191

21922192
def draw(self, renderer):
21932193
# docstring inherited
2194-
self._cachedRenderer = renderer
21952194

21962195
# draw the figure bounding box, perhaps none for white figure
21972196
if not self.get_visible():
@@ -2431,7 +2430,6 @@ def __init__(self,
24312430

24322431
self._axstack = _AxesStack() # track all figure axes and current axes
24332432
self.clear()
2434-
self._cachedRenderer = None
24352433

24362434
# list of child gridspecs for this figure
24372435
self._gridspecs = []
@@ -2569,9 +2567,7 @@ def axes(self):
25692567
get_axes = axes.fget
25702568

25712569
def _get_renderer(self):
2572-
if self._cachedRenderer is not None:
2573-
return self._cachedRenderer
2574-
elif hasattr(self.canvas, 'get_renderer'):
2570+
if hasattr(self.canvas, 'get_renderer'):
25752571
return self.canvas.get_renderer()
25762572
else:
25772573
return _get_renderer(self)
@@ -2965,7 +2961,6 @@ def clear(self, keep_observers=False):
29652961
@allow_rasterization
29662962
def draw(self, renderer):
29672963
# docstring inherited
2968-
self._cachedRenderer = renderer
29692964

29702965
# draw the figure bounding box, perhaps none for white figure
29712966
if not self.get_visible():
@@ -3006,14 +3001,8 @@ def draw_without_rendering(self):
30063001
def draw_artist(self, a):
30073002
"""
30083003
Draw `.Artist` *a* only.
3009-
3010-
This method can only be used after an initial draw of the figure,
3011-
because that creates and caches the renderer needed here.
30123004
"""
3013-
if self._cachedRenderer is None:
3014-
raise AttributeError("draw_artist can only be used after an "
3015-
"initial draw which caches the renderer")
3016-
a.draw(self._cachedRenderer)
3005+
a.draw(self.canvas.get_renderer())
30173006

30183007
def __getstate__(self):
30193008
state = super().__getstate__()
@@ -3023,9 +3012,6 @@ def __getstate__(self):
30233012
# re-attached to another.
30243013
state.pop("canvas")
30253014

3026-
# Set cached renderer to None -- it can't be pickled.
3027-
state["_cachedRenderer"] = None
3028-
30293015
# discard any changes to the dpi due to pixel ratio changes
30303016
state["_dpi"] = state.get('_original_dpi', state['_dpi'])
30313017

lib/matplotlib/tests/test_backend_macosx.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ def test_cached_renderer():
1616
# a fig.canvas.draw() call
1717
fig = plt.figure(1)
1818
fig.canvas.draw()
19-
assert fig._cachedRenderer is not None
19+
assert fig.canvas.get_renderer()._renderer is not None
2020

2121
fig = plt.figure(2)
2222
fig.draw_without_rendering()
23-
assert fig._cachedRenderer is not None
23+
assert fig.canvas.get_renderer()._renderer is not None
2424

2525

2626
@pytest.mark.backend('macosx')

lib/matplotlib/tests/test_image.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,7 @@ def test_empty_imshow(make_norm):
984984
fig.canvas.draw()
985985

986986
with pytest.raises(RuntimeError):
987-
im.make_image(fig._cachedRenderer)
987+
im.make_image(fig.canvas.get_renderer())
988988

989989

990990
def test_imshow_float16():

lib/mpl_toolkits/tests/test_axes_grid1.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ def test_auto_adjustable():
529529
pad = 0.1
530530
make_axes_area_auto_adjustable(ax, pad=pad)
531531
fig.canvas.draw()
532-
tbb = ax.get_tightbbox(fig._cachedRenderer)
532+
tbb = ax.get_tightbbox()
533533
assert tbb.x0 == pytest.approx(pad * fig.dpi)
534534
assert tbb.x1 == pytest.approx(fig.bbox.width - pad * fig.dpi)
535535
assert tbb.y0 == pytest.approx(pad * fig.dpi)

0 commit comments

Comments
 (0)