Skip to content

Commit

Permalink
MNT: consolidate the no-op logic into a RenderBase method
Browse files Browse the repository at this point in the history
Be forgiving about renderer instances that do not inherit from
RendereBase.
  • Loading branch information
tacaswell committed Jun 9, 2020
1 parent 5324ada commit f777177
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 22 deletions.
33 changes: 23 additions & 10 deletions lib/matplotlib/backend_bases.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
The base class for the Toolbar class of each interactive backend.
"""

from contextlib import contextmanager
from contextlib import contextmanager, suppress
from enum import Enum, IntEnum
import functools
import importlib
Expand Down Expand Up @@ -709,6 +709,23 @@ def stop_filter(self, filter_func):
Currently only supported by the agg renderer.
"""

def _draw_disabled(self):
"""
Context manager to temporary disable drawing.
This is used for getting the drawn size of Artists. This lets us
run the draw process to update any Python state but does not pay the
cost of the draw_XYZ calls on the canvas.
"""
no_ops = {
meth_name: lambda *args, **kwargs: None
for meth_name in dir(RendererBase)
if (meth_name.startswith("draw_")
or meth_name in ["open_group", "close_group"])
}

return _setattr_cm(self, **no_ops)


class GraphicsContextBase:
"""An abstract base class that provides color, line styles, etc."""
Expand Down Expand Up @@ -1509,7 +1526,7 @@ def _get_renderer(figure, print_method=None):
the figure.
If you need a renderer without any active draw methods use
cbook._setattr_cm to temporary patch them out at your call site.
renderer._draw_disabled to temporary patch them out at your call site.
"""
# This is implemented by triggering a draw, then immediately jumping out of
Expand Down Expand Up @@ -2089,14 +2106,10 @@ def print_figure(
functools.partial(
print_method, orientation=orientation)
)
no_ops = {
meth_name: lambda *args, **kwargs: None
for meth_name in dir(RendererBase)
if (meth_name.startswith("draw_")
or meth_name in ["open_group", "close_group"])
}

with _setattr_cm(renderer, **no_ops):
ctx = (renderer._draw_disabled()
if hasattr(renderer, '_draw_disabled')
else suppress())
with ctx:
self.figure.draw(renderer)

bbox_inches = self.figure.get_tightbbox(
Expand Down
17 changes: 5 additions & 12 deletions lib/matplotlib/figure.py
Original file line number Diff line number Diff line change
Expand Up @@ -2392,9 +2392,7 @@ def tight_layout(self, renderer=None, pad=1.08, h_pad=None, w_pad=None,

from .tight_layout import (
get_renderer, get_subplotspec_list, get_tight_layout_figure)
from .cbook import _setattr_cm
from .backend_bases import RendererBase

from contextlib import suppress
subplotspec_list = get_subplotspec_list(self.axes)
if None in subplotspec_list:
cbook._warn_external("This figure includes Axes that are not "
Expand All @@ -2403,15 +2401,10 @@ def tight_layout(self, renderer=None, pad=1.08, h_pad=None, w_pad=None,

if renderer is None:
renderer = get_renderer(self)

no_ops = {
meth_name: lambda *args, **kwargs: None
for meth_name in dir(RendererBase)
if (meth_name.startswith("draw_")
or meth_name in ["open_group", "close_group"])
}

with _setattr_cm(renderer, **no_ops):
ctx = (renderer._draw_disabled()
if hasattr(renderer, '_draw_disabled')
else suppress())
with ctx:
kwargs = get_tight_layout_figure(
self, self.axes, subplotspec_list, renderer,
pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)
Expand Down

0 comments on commit f777177

Please sign in to comment.