diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index 5bdcb6c6a64f..97b1b314819f 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -1534,7 +1534,6 @@ def _get_renderer(figure, print_method=None): If you need a renderer without any active draw methods use renderer._draw_disabled to temporary patch them out at your call site. - """ # This is implemented by triggering a draw, then immediately jumping out of # Figure.draw() by raising an exception. @@ -1545,15 +1544,23 @@ class Done(Exception): def _draw(renderer): raise Done(renderer) with cbook._setattr_cm(figure, draw=_draw): + orig_canvas = figure.canvas if print_method is None: fmt = figure.canvas.get_default_filetype() - print_method = getattr(figure.canvas, f"print_{fmt}") + # Even for a canvas' default output type, a canvas switch may be + # needed, e.g. for FigureCanvasBase. + print_method = getattr( + figure.canvas._get_output_canvas(None, fmt), f"print_{fmt}") try: print_method(io.BytesIO(), dpi=figure.dpi) except Done as exc: renderer, = figure._cachedRenderer, = exc.args - - return renderer + return renderer + else: + raise RuntimeError(f"{print_method} did not call Figure.draw, so " + f"no renderer is available") + finally: + figure.canvas = orig_canvas def _is_non_interactive_terminal_ipython(ip): diff --git a/lib/matplotlib/backends/backend_template.py b/lib/matplotlib/backends/backend_template.py index bd5cab86deb3..921e4060429e 100644 --- a/lib/matplotlib/backends/backend_template.py +++ b/lib/matplotlib/backends/backend_template.py @@ -208,6 +208,7 @@ def print_foo(self, filename, *args, **kwargs): to their original values after this call, so you don't need to save and restore them. """ + self.draw() def get_default_filetype(self): return 'foo'