Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 542c664

Browse filesBrowse files
authored
Merge pull request #18111 from QuLogic/auto-backport-of-pr-18089-on-v3.3.x
Backport PR #18089 on branch v3.3.x
2 parents 6f669dd + 01c41a0 commit 542c664
Copy full SHA for 542c664

File tree

Expand file treeCollapse file tree

2 files changed

+49
-38
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+49
-38
lines changed

‎lib/matplotlib/tests/test_bbox_tight.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tests/test_bbox_tight.py
+7-1Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,13 @@ def test_noop_tight_bbox():
125125
ax.get_yaxis().set_visible(False)
126126

127127
data = np.arange(x_size * y_size).reshape(y_size, x_size)
128-
ax.imshow(data)
128+
ax.imshow(data, rasterized=True)
129+
130+
# When a rasterized Artist is included, a mixed-mode renderer does
131+
# additional bbox adjustment. It should also be a no-op, and not affect the
132+
# next save.
133+
fig.savefig(BytesIO(), bbox_inches='tight', pad_inches=0, format='pdf')
134+
129135
out = BytesIO()
130136
fig.savefig(out, bbox_inches='tight', pad_inches=0)
131137
out.seek(0)

‎lib/matplotlib/tight_bbox.py

Copy file name to clipboardExpand all lines: lib/matplotlib/tight_bbox.py
+42-37Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22
Helper module for the *bbox_inches* parameter in `.Figure.savefig`.
33
"""
44

5-
import contextlib
6-
7-
from matplotlib.cbook import _setattr_cm
85
from matplotlib.transforms import Bbox, TransformedBbox, Affine2D
96

107

@@ -18,55 +15,63 @@ def adjust_bbox(fig, bbox_inches, fixed_dpi=None):
1815
changes, the scale of the original figure is conserved. A
1916
function which restores the original values are returned.
2017
"""
21-
def no_op_apply_aspect(position=None):
22-
return
23-
24-
stack = contextlib.ExitStack()
18+
origBbox = fig.bbox
19+
origBboxInches = fig.bbox_inches
20+
orig_tight_layout = fig.get_tight_layout()
21+
_boxout = fig.transFigure._boxout
2522

26-
stack.callback(fig.set_tight_layout, fig.get_tight_layout())
2723
fig.set_tight_layout(False)
2824

25+
old_aspect = []
26+
locator_list = []
27+
sentinel = object()
2928
for ax in fig.axes:
30-
pos = ax.get_position(original=False).frozen()
31-
32-
def _l(a, r, pos=pos):
33-
return pos
34-
35-
stack.callback(ax.set_axes_locator, ax.get_axes_locator())
36-
ax.set_axes_locator(_l)
37-
38-
# override the method that enforces the aspect ratio
39-
# on the Axes
40-
stack.enter_context(_setattr_cm(ax, apply_aspect=no_op_apply_aspect))
41-
42-
if fixed_dpi is not None:
43-
tr = Affine2D().scale(fixed_dpi)
44-
dpi_scale = fixed_dpi / fig.dpi
45-
else:
46-
tr = Affine2D().scale(fig.dpi)
47-
dpi_scale = 1.
29+
locator_list.append(ax.get_axes_locator())
30+
current_pos = ax.get_position(original=False).frozen()
31+
ax.set_axes_locator(lambda a, r, _pos=current_pos: _pos)
32+
# override the method that enforces the aspect ratio on the Axes
33+
if 'apply_aspect' in ax.__dict__:
34+
old_aspect.append(ax.apply_aspect)
35+
else:
36+
old_aspect.append(sentinel)
37+
ax.apply_aspect = lambda pos=None: None
38+
39+
def restore_bbox():
40+
for ax, loc, aspect in zip(fig.axes, locator_list, old_aspect):
41+
ax.set_axes_locator(loc)
42+
if aspect is sentinel:
43+
# delete our no-op function which un-hides the original method
44+
del ax.apply_aspect
45+
else:
46+
ax.apply_aspect = aspect
47+
48+
fig.bbox = origBbox
49+
fig.bbox_inches = origBboxInches
50+
fig.set_tight_layout(orig_tight_layout)
51+
fig.transFigure._boxout = _boxout
52+
fig.transFigure.invalidate()
53+
fig.patch.set_bounds(0, 0, 1, 1)
54+
55+
if fixed_dpi is None:
56+
fixed_dpi = fig.dpi
57+
tr = Affine2D().scale(fixed_dpi)
58+
dpi_scale = fixed_dpi / fig.dpi
4859

4960
_bbox = TransformedBbox(bbox_inches, tr)
5061

51-
stack.enter_context(
52-
_setattr_cm(fig, bbox_inches=Bbox.from_bounds(
53-
0, 0, bbox_inches.width, bbox_inches.height)))
62+
fig.bbox_inches = Bbox.from_bounds(0, 0,
63+
bbox_inches.width, bbox_inches.height)
5464
x0, y0 = _bbox.x0, _bbox.y0
5565
w1, h1 = fig.bbox.width * dpi_scale, fig.bbox.height * dpi_scale
56-
stack.enter_context(
57-
_setattr_cm(fig.transFigure,
58-
_boxout=Bbox.from_bounds(-x0, -y0, w1, h1)))
66+
fig.transFigure._boxout = Bbox.from_bounds(-x0, -y0, w1, h1)
5967
fig.transFigure.invalidate()
60-
stack.callback(fig.transFigure.invalidate)
6168

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

65-
stack.callback(fig.patch.set_bounds, 0, 0, 1, 1)
6671
fig.patch.set_bounds(x0 / w1, y0 / h1,
6772
fig.bbox.width / w1, fig.bbox.height / h1)
6873

69-
return stack.close
74+
return restore_bbox
7075

7176

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

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.