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 8605579

Browse filesBrowse files
committed
Merge pull request #1448 from pelson/bbox_tight_all_artists
```bbox_inches="tight"``` support for *all* figure artists.
2 parents cf6b26f + 6569ca7 commit 8605579
Copy full SHA for 8605579

18 files changed

+1638
-27
lines changed

‎.travis.yml

Copy file name to clipboardExpand all lines: .travis.yml
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ install:
2222
script:
2323
- mkdir ../foo
2424
- cd ../foo
25-
- python ../matplotlib/tests.py
25+
- python ../matplotlib/tests.py -sv

‎doc/users/whats_new.rst

Copy file name to clipboardExpand all lines: doc/users/whats_new.rst
+7Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ They may be symmetric or weighted.
4040

4141
.. plot:: mpl_examples/pylab_examples/stackplot_demo2.py
4242

43+
Improved ``bbox_inches="tight"`` functionality
44+
----------------------------------------------
45+
Passing ``bbox_inches="tight"`` through to :func:`plt.save` now takes into account
46+
*all* artists on a figure - this was previously not the case and led to several
47+
corner cases which did not function as expected.
48+
49+
4350
Remember save directory
4451
-----------------------
4552
Martin Spacek made the save figure dialog remember the last directory saved

‎lib/matplotlib/artist.py

Copy file name to clipboardExpand all lines: lib/matplotlib/artist.py
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,15 @@ def get_axes(self):
180180
"""
181181
return self.axes
182182

183+
def get_window_extent(self, renderer):
184+
"""
185+
Get the axes bounding box in display space.
186+
Subclasses should override for inclusion in the bounding box
187+
"tight" calculation. Default is to return an empty bounding
188+
box at 0, 0.
189+
"""
190+
return Bbox([[0, 0], [0, 0]])
191+
183192
def add_callback(self, func):
184193
"""
185194
Adds a callback function that will be called whenever one of

‎lib/matplotlib/axes.py

Copy file name to clipboardExpand all lines: lib/matplotlib/axes.py
+2-7Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9076,13 +9076,8 @@ def matshow(self, Z, **kwargs):
90769076
return im
90779077

90789078
def get_default_bbox_extra_artists(self):
9079-
bbox_extra_artists = [t for t in self.texts if t.get_visible()]
9080-
if self.legend_:
9081-
bbox_extra_artists.append(self.legend_)
9082-
if self.tables:
9083-
for t in self.tables:
9084-
bbox_extra_artists.append(t)
9085-
return bbox_extra_artists
9079+
return [artist for artist in self.get_children()
9080+
if artist.get_visible()]
90869081

90879082
def get_tightbbox(self, renderer, call_axes_locator=True):
90889083
"""

‎lib/matplotlib/backend_bases.py

Copy file name to clipboardExpand all lines: lib/matplotlib/backend_bases.py
+19-8Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2094,15 +2094,26 @@ def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w',
20942094
renderer = self.figure._cachedRenderer
20952095
bbox_inches = self.figure.get_tightbbox(renderer)
20962096

2097-
bbox_extra_artists = kwargs.pop("bbox_extra_artists", None)
2098-
if bbox_extra_artists is None:
2099-
bbox_extra_artists = self.figure.get_default_bbox_extra_artists()
2097+
bbox_artists = kwargs.pop("bbox_extra_artists", None)
2098+
if bbox_artists is None:
2099+
bbox_artists = self.figure.get_default_bbox_extra_artists()
2100+
2101+
bbox_filtered = []
2102+
for a in bbox_artists:
2103+
bbox = a.get_window_extent(renderer)
2104+
if a.get_clip_on():
2105+
clip_box = a.get_clip_box()
2106+
if clip_box is not None:
2107+
bbox = Bbox.intersection(bbox, clip_box)
2108+
clip_path = a.get_clip_path()
2109+
if clip_path is not None and bbox is not None:
2110+
clip_path = clip_path.get_fully_transformed_path()
2111+
bbox = Bbox.intersection(bbox,
2112+
clip_path.get_extents())
2113+
if bbox is not None and (bbox.width != 0 or
2114+
bbox.height != 0):
2115+
bbox_filtered.append(bbox)
21002116

2101-
bb = [a.get_window_extent(renderer)
2102-
for a in bbox_extra_artists]
2103-
2104-
bbox_filtered = [b for b in bb
2105-
if b.width != 0 or b.height != 0]
21062117
if bbox_filtered:
21072118
_bbox = Bbox.union(bbox_filtered)
21082119
trans = Affine2D().scale(1.0 / self.figure.dpi)

‎lib/matplotlib/collections.py

Copy file name to clipboardExpand all lines: lib/matplotlib/collections.py
+3-4Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,9 @@ def get_datalim(self, transData):
193193
return result
194194

195195
def get_window_extent(self, renderer):
196-
bbox = self.get_datalim(transforms.IdentityTransform())
197-
#TODO:check to ensure that this does not fail for
198-
#cases other than scatter plot legend
199-
return bbox
196+
# TODO:check to ensure that this does not fail for
197+
# cases other than scatter plot legend
198+
return self.get_datalim(transforms.IdentityTransform())
200199

201200
def _prepare_points(self):
202201
"""Point prep for drawing and hit testing"""

‎lib/matplotlib/figure.py

Copy file name to clipboardExpand all lines: lib/matplotlib/figure.py
+6-3Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1504,11 +1504,14 @@ def waitforbuttonpress(self, timeout=-1):
15041504
return blocking_input(timeout=timeout)
15051505

15061506
def get_default_bbox_extra_artists(self):
1507-
bbox_extra_artists = [t for t in self.texts if t.get_visible()]
1507+
bbox_artists = [artist for artist in self.get_children()
1508+
if artist.get_visible()]
15081509
for ax in self.axes:
15091510
if ax.get_visible():
1510-
bbox_extra_artists.extend(ax.get_default_bbox_extra_artists())
1511-
return bbox_extra_artists
1511+
bbox_artists.extend(ax.get_default_bbox_extra_artists())
1512+
# we don't want the figure's patch to influence the bbox calculation
1513+
bbox_artists.remove(self.patch)
1514+
return bbox_artists
15121515

15131516
def get_tightbbox(self, renderer):
15141517
"""

‎lib/matplotlib/lines.py

Copy file name to clipboardExpand all lines: lib/matplotlib/lines.py
+4-4Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -374,10 +374,10 @@ def set_picker(self, p):
374374
self._picker = p
375375

376376
def get_window_extent(self, renderer):
377-
bbox = Bbox.unit()
378-
bbox.update_from_data_xy(
379-
self.get_transform().transform(self.get_xydata()),
380-
ignore=True)
377+
bbox = Bbox([[0, 0], [0, 0]])
378+
trans_data_to_xy = self.get_transform().transform
379+
bbox.update_from_data_xy(trans_data_to_xy(self.get_xydata()),
380+
ignore=True)
381381
# correct for marker size, if any
382382
if self._marker:
383383
ms = (self._markersize / 72.0 * self.figure.dpi) * 0.5

‎lib/matplotlib/table.py

Copy file name to clipboardExpand all lines: lib/matplotlib/table.py
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,8 @@ def __init__(self, ax, loc=None, bbox=None):
202202
self._autoColumns = []
203203
self._autoFontsize = True
204204

205+
self.set_clip_on(False)
206+
205207
self._cachedRenderer = None
206208

207209
def add_cell(self, row, col, *args, **kwargs):
Loading

0 commit comments

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