Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 602be07

Browse files
committed
Convert adjust_bbox to use ExitStack.
This allows us to use `_setattr_cm` and not worry about manually restoring things or handling weird attributes ourselves.
1 parent f820c27 commit 602be07

File tree

1 file changed

+21
-35
lines changed

1 file changed

+21
-35
lines changed

lib/matplotlib/tight_bbox.py

Lines changed: 21 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
Helper module for the *bbox_inches* parameter in `.Figure.savefig`.
33
"""
44

5+
import contextlib
6+
7+
from matplotlib.cbook import _setattr_cm
58
from matplotlib.transforms import Bbox, TransformedBbox, Affine2D
69

710

@@ -18,46 +21,23 @@ def adjust_bbox(fig, bbox_inches, fixed_dpi=None):
1821
def no_op_apply_aspect(position=None):
1922
return
2023

21-
origBbox = fig.bbox
22-
origBboxInches = fig.bbox_inches
23-
orig_tight_layout = fig.get_tight_layout()
24-
_boxout = fig.transFigure._boxout
24+
stack = contextlib.ExitStack()
2525

26+
stack.callback(fig.set_tight_layout, fig.get_tight_layout())
2627
fig.set_tight_layout(False)
27-
old_aspect = []
28-
locator_list = []
29-
sentinel = object()
28+
3029
for ax in fig.axes:
3130
pos = ax.get_position(original=False).frozen()
32-
locator_list.append(ax.get_axes_locator())
3331

3432
def _l(a, r, pos=pos):
3533
return pos
34+
35+
stack.callback(ax.set_axes_locator, ax.get_axes_locator())
3636
ax.set_axes_locator(_l)
37+
3738
# override the method that enforces the aspect ratio
3839
# on the Axes
39-
if 'apply_aspect' in ax.__dict__:
40-
old_aspect.append(ax.apply_aspect)
41-
else:
42-
old_aspect.append(sentinel)
43-
ax.apply_aspect = no_op_apply_aspect
44-
45-
def restore_bbox():
46-
for ax, loc, aspect in zip(fig.axes, locator_list, old_aspect):
47-
ax.set_axes_locator(loc)
48-
if aspect is sentinel:
49-
# delete our no-op function which un-hides the
50-
# original method
51-
del ax.apply_aspect
52-
else:
53-
ax.apply_aspect = aspect
54-
55-
fig.bbox = origBbox
56-
fig.bbox_inches = origBboxInches
57-
fig.set_tight_layout(orig_tight_layout)
58-
fig.transFigure._boxout = _boxout
59-
fig.transFigure.invalidate()
60-
fig.patch.set_bounds(0, 0, 1, 1)
40+
stack.enter_context(_setattr_cm(ax, apply_aspect=no_op_apply_aspect))
6141

6242
if fixed_dpi is not None:
6343
tr = Affine2D().scale(fixed_dpi)
@@ -68,19 +48,25 @@ def restore_bbox():
6848

6949
_bbox = TransformedBbox(bbox_inches, tr)
7050

71-
fig.bbox_inches = Bbox.from_bounds(0, 0,
72-
bbox_inches.width, bbox_inches.height)
51+
stack.enter_context(
52+
_setattr_cm(fig, bbox_inches=Bbox.from_bounds(
53+
0, 0, bbox_inches.width, bbox_inches.height)))
7354
x0, y0 = _bbox.x0, _bbox.y0
7455
w1, h1 = fig.bbox.width * dpi_scale, fig.bbox.height * dpi_scale
75-
fig.transFigure._boxout = Bbox.from_bounds(-x0, -y0, w1, h1)
56+
stack.enter_context(
57+
_setattr_cm(fig.transFigure,
58+
_boxout=Bbox.from_bounds(-x0, -y0, w1, h1)))
7659
fig.transFigure.invalidate()
60+
stack.callback(fig.transFigure.invalidate)
7761

78-
fig.bbox = TransformedBbox(fig.bbox_inches, tr)
62+
stack.enter_context(
63+
_setattr_cm(fig, bbox=TransformedBbox(fig.bbox_inches, tr)))
7964

65+
stack.callback(fig.patch.set_bounds, 0, 0, 1, 1)
8066
fig.patch.set_bounds(x0 / w1, y0 / h1,
8167
fig.bbox.width / w1, fig.bbox.height / h1)
8268

83-
return restore_bbox
69+
return stack.close
8470

8571

8672
def process_figure_for_rasterizing(fig, bbox_inches_restore, fixed_dpi=None):

0 commit comments

Comments
 (0)