Skip to content

Commit dc7b785

Browse files
authored
Merge pull request #23202 from greglucas/cached-renderer
MNT: Remove cached renderer from figure
2 parents 37300c3 + 333af74 commit dc7b785

File tree

9 files changed

+21
-39
lines changed

9 files changed

+21
-39
lines changed
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

+4-15
Original file line numberDiff line numberDiff line change
@@ -3068,33 +3068,22 @@ def draw(self, renderer):
30683068
def draw_artist(self, a):
30693069
"""
30703070
Efficiently redraw a single artist.
3071-
3072-
This method can only be used after an initial draw of the figure,
3073-
because that creates and caches the renderer needed here.
30743071
"""
3075-
if self.figure._cachedRenderer is None:
3076-
raise AttributeError("draw_artist can only be used after an "
3077-
"initial draw which caches the renderer")
3078-
a.draw(self.figure._cachedRenderer)
3072+
a.draw(self.figure.canvas.get_renderer())
30793073

30803074
def redraw_in_frame(self):
30813075
"""
30823076
Efficiently redraw Axes data, but not axis ticks, labels, etc.
3083-
3084-
This method can only be used after an initial draw which caches the
3085-
renderer.
30863077
"""
3087-
if self.figure._cachedRenderer is None:
3088-
raise AttributeError("redraw_in_frame can only be used after an "
3089-
"initial draw which caches the renderer")
30903078
with ExitStack() as stack:
30913079
for artist in [*self._axis_map.values(),
30923080
self.title, self._left_title, self._right_title]:
30933081
stack.enter_context(artist._cm_set(visible=False))
3094-
self.draw(self.figure._cachedRenderer)
3082+
self.draw(self.figure.canvas.get_renderer())
30953083

3084+
@_api.deprecated("3.6", alternative="Axes.figure.canvas.get_renderer()")
30963085
def get_renderer_cache(self):
3097-
return self.figure._cachedRenderer
3086+
return self.figure.canvas.get_renderer()
30983087

30993088
# Axes rectangle characteristics
31003089

lib/matplotlib/backend_bases.py

+2-3
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

+3
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

+1-1
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

+2-16
Original file line numberDiff line numberDiff line change
@@ -2253,7 +2253,6 @@ def axes(self):
22532253

22542254
def draw(self, renderer):
22552255
# docstring inherited
2256-
self._cachedRenderer = renderer
22572256

22582257
# draw the figure bounding box, perhaps none for white figure
22592258
if not self.get_visible():
@@ -2493,7 +2492,6 @@ def __init__(self,
24932492

24942493
self._axstack = _AxesStack() # track all figure axes and current axes
24952494
self.clear()
2496-
self._cachedRenderer = None
24972495

24982496
# list of child gridspecs for this figure
24992497
self._gridspecs = []
@@ -2655,9 +2653,7 @@ def axes(self):
26552653
get_axes = axes.fget
26562654

26572655
def _get_renderer(self):
2658-
if self._cachedRenderer is not None:
2659-
return self._cachedRenderer
2660-
elif hasattr(self.canvas, 'get_renderer'):
2656+
if hasattr(self.canvas, 'get_renderer'):
26612657
return self.canvas.get_renderer()
26622658
else:
26632659
return _get_renderer(self)
@@ -3051,7 +3047,6 @@ def clear(self, keep_observers=False):
30513047
@allow_rasterization
30523048
def draw(self, renderer):
30533049
# docstring inherited
3054-
self._cachedRenderer = renderer
30553050

30563051
# draw the figure bounding box, perhaps none for white figure
30573052
if not self.get_visible():
@@ -3092,14 +3087,8 @@ def draw_without_rendering(self):
30923087
def draw_artist(self, a):
30933088
"""
30943089
Draw `.Artist` *a* only.
3095-
3096-
This method can only be used after an initial draw of the figure,
3097-
because that creates and caches the renderer needed here.
30983090
"""
3099-
if self._cachedRenderer is None:
3100-
raise AttributeError("draw_artist can only be used after an "
3101-
"initial draw which caches the renderer")
3102-
a.draw(self._cachedRenderer)
3091+
a.draw(self.canvas.get_renderer())
31033092

31043093
def __getstate__(self):
31053094
state = super().__getstate__()
@@ -3109,9 +3098,6 @@ def __getstate__(self):
31093098
# re-attached to another.
31103099
state.pop("canvas")
31113100

3112-
# Set cached renderer to None -- it can't be pickled.
3113-
state["_cachedRenderer"] = None
3114-
31153101
# discard any changes to the dpi due to pixel ratio changes
31163102
state["_dpi"] = state.get('_original_dpi', state['_dpi'])
31173103

lib/matplotlib/tests/test_backend_macosx.py

+2-2
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

+1-1
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

+1-1
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ def test_auto_adjustable():
552552
pad = 0.1
553553
make_axes_area_auto_adjustable(ax, pad=pad)
554554
fig.canvas.draw()
555-
tbb = ax.get_tightbbox(fig._cachedRenderer)
555+
tbb = ax.get_tightbbox()
556556
assert tbb.x0 == pytest.approx(pad * fig.dpi)
557557
assert tbb.x1 == pytest.approx(fig.bbox.width - pad * fig.dpi)
558558
assert tbb.y0 == pytest.approx(pad * fig.dpi)

0 commit comments

Comments
 (0)