From b8bc21f4a5854a1cb5778b9ee1db41e1d352948a Mon Sep 17 00:00:00 2001 From: Phil Elson Date: Wed, 13 Mar 2013 13:47:17 +0000 Subject: [PATCH 1/2] bbox_inches=tight support for *all* figure artists. --- .travis.yml | 2 +- lib/matplotlib/artist.py | 9 + lib/matplotlib/axes.py | 9 +- lib/matplotlib/backend_bases.py | 29 +- lib/matplotlib/collections.py | 7 +- lib/matplotlib/figure.py | 9 +- lib/matplotlib/lines.py | 8 +- lib/matplotlib/table.py | 2 + .../bbox_inches_tight_clipping.pdf | Bin 0 -> 2112 bytes .../bbox_inches_tight_clipping.png | Bin 0 -> 10246 bytes .../bbox_inches_tight_clipping.svg | 296 ++++ .../bbox_inches_tight_suptile_legend.pdf | Bin 0 -> 12421 bytes .../bbox_inches_tight_suptile_legend.png | Bin 0 -> 33388 bytes .../bbox_inches_tight_suptile_legend.svg | 1193 +++++++++++++++++ lib/matplotlib/tests/test_bbox_tight.py | 45 + lib/matplotlib/tests/test_transforms.py | 26 + lib/matplotlib/transforms.py | 25 + 17 files changed, 1633 insertions(+), 27 deletions(-) create mode 100644 lib/matplotlib/tests/baseline_images/test_bbox_tight/bbox_inches_tight_clipping.pdf create mode 100644 lib/matplotlib/tests/baseline_images/test_bbox_tight/bbox_inches_tight_clipping.png create mode 100644 lib/matplotlib/tests/baseline_images/test_bbox_tight/bbox_inches_tight_clipping.svg create mode 100644 lib/matplotlib/tests/baseline_images/test_bbox_tight/bbox_inches_tight_suptile_legend.pdf create mode 100644 lib/matplotlib/tests/baseline_images/test_bbox_tight/bbox_inches_tight_suptile_legend.png create mode 100644 lib/matplotlib/tests/baseline_images/test_bbox_tight/bbox_inches_tight_suptile_legend.svg diff --git a/.travis.yml b/.travis.yml index da3c6434a7aa..0a84c2d30d19 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,4 +22,4 @@ install: script: - mkdir ../foo - cd ../foo - - python ../matplotlib/tests.py + - python ../matplotlib/tests.py -sv diff --git a/lib/matplotlib/artist.py b/lib/matplotlib/artist.py index 5880180ed5d3..8670d3da6530 100644 --- a/lib/matplotlib/artist.py +++ b/lib/matplotlib/artist.py @@ -180,6 +180,15 @@ def get_axes(self): """ return self.axes + def get_window_extent(self, renderer): + """ + Get the axes bounding box in display space. + Subclasses should override for inclusion in the bounding box + "tight" calculation. Default is to return an empty bounding + box at 0, 0. + """ + return Bbox([[0, 0], [0, 0]]) + def add_callback(self, func): """ Adds a callback function that will be called whenever one of diff --git a/lib/matplotlib/axes.py b/lib/matplotlib/axes.py index 42c7dc93b08c..ca35346a16f9 100644 --- a/lib/matplotlib/axes.py +++ b/lib/matplotlib/axes.py @@ -9072,13 +9072,8 @@ def matshow(self, Z, **kwargs): return im def get_default_bbox_extra_artists(self): - bbox_extra_artists = [t for t in self.texts if t.get_visible()] - if self.legend_: - bbox_extra_artists.append(self.legend_) - if self.tables: - for t in self.tables: - bbox_extra_artists.append(t) - return bbox_extra_artists + return [artist for artist in self.get_children() + if artist.get_visible()] def get_tightbbox(self, renderer, call_axes_locator=True): """ diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index abcf66c790ad..d639fb1b71db 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -2092,15 +2092,28 @@ def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w', renderer = self.figure._cachedRenderer bbox_inches = self.figure.get_tightbbox(renderer) - bbox_extra_artists = kwargs.pop("bbox_extra_artists", None) - if bbox_extra_artists is None: - bbox_extra_artists = self.figure.get_default_bbox_extra_artists() + bbox_artists = kwargs.pop("bbox_extra_artists", None) + if bbox_artists is None: + bbox_artists = self.figure.get_default_bbox_extra_artists() + + bbox_filtered = [] + for a in bbox_artists: + bbox = a.get_window_extent(renderer) + # print('{0:40} - {1.width:5}, {1.height:5} ' + # '{1}'.format(type(a), bbox)) + if a.get_clip_on(): + clip_box = a.get_clip_box() + if clip_box is not None: + bbox = Bbox.intersection(bbox, clip_box) + clip_path = a.get_clip_path() + if clip_path is not None and bbox is not None: + clip_path = clip_path.get_fully_transformed_path() + bbox = Bbox.intersection(bbox, + clip_path.get_extents()) + if bbox is not None and (bbox.width != 0 or + bbox.height != 0): + bbox_filtered.append(bbox) - bb = [a.get_window_extent(renderer) - for a in bbox_extra_artists] - - bbox_filtered = [b for b in bb - if b.width != 0 or b.height != 0] if bbox_filtered: _bbox = Bbox.union(bbox_filtered) trans = Affine2D().scale(1.0 / self.figure.dpi) diff --git a/lib/matplotlib/collections.py b/lib/matplotlib/collections.py index 7862adfc9132..867306a4c873 100644 --- a/lib/matplotlib/collections.py +++ b/lib/matplotlib/collections.py @@ -193,10 +193,9 @@ def get_datalim(self, transData): return result def get_window_extent(self, renderer): - bbox = self.get_datalim(transforms.IdentityTransform()) - #TODO:check to ensure that this does not fail for - #cases other than scatter plot legend - return bbox + # TODO:check to ensure that this does not fail for + # cases other than scatter plot legend + return self.get_datalim(transforms.IdentityTransform()) def _prepare_points(self): """Point prep for drawing and hit testing""" diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index 03a9966bb0d9..3b97ca45328d 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -1504,11 +1504,14 @@ def waitforbuttonpress(self, timeout=-1): return blocking_input(timeout=timeout) def get_default_bbox_extra_artists(self): - bbox_extra_artists = [t for t in self.texts if t.get_visible()] + bbox_artists = [artist for artist in self.get_children() + if artist.get_visible()] for ax in self.axes: if ax.get_visible(): - bbox_extra_artists.extend(ax.get_default_bbox_extra_artists()) - return bbox_extra_artists + bbox_artists.extend(ax.get_default_bbox_extra_artists()) + # we don't want the figure's patch to influence the bbox calculation + bbox_artists.remove(self.patch) + return bbox_artists def get_tightbbox(self, renderer): """ diff --git a/lib/matplotlib/lines.py b/lib/matplotlib/lines.py index b30e89111580..6a080eaa4e65 100644 --- a/lib/matplotlib/lines.py +++ b/lib/matplotlib/lines.py @@ -374,10 +374,10 @@ def set_picker(self, p): self._picker = p def get_window_extent(self, renderer): - bbox = Bbox.unit() - bbox.update_from_data_xy( - self.get_transform().transform(self.get_xydata()), - ignore=True) + bbox = Bbox([[0, 0], [0, 0]]) + trans_data_to_xy = self.get_transform().transform + bbox.update_from_data_xy(trans_data_to_xy(self.get_xydata()), + ignore=True) # correct for marker size, if any if self._marker: ms = (self._markersize / 72.0 * self.figure.dpi) * 0.5 diff --git a/lib/matplotlib/table.py b/lib/matplotlib/table.py index b0036bc953c5..7d3a6813dee2 100644 --- a/lib/matplotlib/table.py +++ b/lib/matplotlib/table.py @@ -202,6 +202,8 @@ def __init__(self, ax, loc=None, bbox=None): self._autoColumns = [] self._autoFontsize = True + self.set_clip_on(False) + self._cachedRenderer = None def add_cell(self, row, col, *args, **kwargs): diff --git a/lib/matplotlib/tests/baseline_images/test_bbox_tight/bbox_inches_tight_clipping.pdf b/lib/matplotlib/tests/baseline_images/test_bbox_tight/bbox_inches_tight_clipping.pdf new file mode 100644 index 0000000000000000000000000000000000000000..47214a6462678bec416a584e7b37cefed6772c1f GIT binary patch literal 2112 zcmZuyYfuwc6rM`4OspWbJOmtXr;V5qvbza+p&$?l@~V)~5oJJ^WCP)mjme@x3=CS8 zms%W0bWl;tw2UH;78Ipbv7$iLjx*{^E1(opsGv|R13rSin-IdIn;)Bd?zv~rIrsa% z!;B4;_+o572D7FMoWH`r01C*IbjI4X0Ey4h5C9S56rM?@0wfksC3JuT9i$*IkU^*w zw4-pwfrJey>4cmD0<#Z1Kv9HN4S4jDfy8P_xs0GdA`BHOf#C@~1(1j=7&c_;EuMNu zfFyu~>8WrTg;NCZvjmW(;R=;H74R+LC8U}HT=RchIv5HK)&jz{WVQy-rHEw!2_?3x zj)*N3iBP_fi}}%sO9>sBt(C)O(an)sqtpFkAYzy`46Oqq^PVkpdTmWyqRNDw z1BfIOmLE#UNd>%!XhNMzr2&k-BJ&OCC@q0!G4v;lM_bjOU`zH5=P|AYbuG&sYB+Q{ za(#gFwx=H~X$(n>eJoC{%$KG0ZTpG!XFIdV^mbg(Q<}Qpw8PDGAT@umW5tN6^@YQ_ zVFR1lSarZpd-vGpp(8h4(=+1JQwlzo3yiM${Z~adPTgTuZTvp{wA<&gm+enhm&BdC z>E2nCdGX??N9&%)Z$E0O|F-Z52#j!STbDOhX>#(KxK+1dx2exJ&~Z|K@QExj*Km1! z?kb$T{k$h&om8>8J^xg{GTFUpRF&L3{;2!?*q)^3Q_6+!%Cu$FTz{4L+?-j5kgGWo%4+_*&)TPm&C+7rWp2vXX z61Cdt-zZU?Y|OWzKZm*e_tGESau~x#E;T5axKB=$arepckjmb~YrTi^ey!Ubef-s$ z*IrL1eDg;<^Ez2IMgG0xqsy+2c}@;oOTe=GlHMHc`c3ybq3Phyw|b>s7022PZ(2Op z{_+0I^2-A~FT=O4@ONgj+B+OwhHpQpa$e-(bFiSwwfJo5K8cu$W~H4!5!qU@{hz%d zK265>YUZIA@#vC!jJQw5D`Vo%)@~2QU!mCtyfVTny){gioQoi`aeaccT5{oDkml~5 zv|69TOTJsIx$vQTRpG*hXOqzx75bs(+MY9u4Lh^0JX(l*vt-xV4}y$CI~+XkJ3Dqd zD1FB_wbV4Nc1_**G`Xs_&1=;!#cRG8?lCQhED0>6IXnfTDK?wIMWc`>K&=d?DK-U6 z8(L{fTG1MeSvVF9P&Utsb{l&UId0y7yt19AHDO**n%MJ( zKXdpx_sdp$&GjvrvcEj)Iut9%$-XFiMPvQ-Hly5SmtCK3c_*v(IBs)QY!Ko%X(D343EkBA8?e!jE#*||ko{k|SvL_wdEZ6R`F xRVJY|kNOC;k_6_PgyTv|k~9F!qf4gRNx&vrpp9!Ob6YV1kIP^(!!}45{{djd*)#wE literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/baseline_images/test_bbox_tight/bbox_inches_tight_clipping.png b/lib/matplotlib/tests/baseline_images/test_bbox_tight/bbox_inches_tight_clipping.png new file mode 100644 index 0000000000000000000000000000000000000000..95682004be4060af5784db97a6d266f13d92cda7 GIT binary patch literal 10246 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/baseline_images/test_bbox_tight/bbox_inches_tight_suptile_legend.pdf b/lib/matplotlib/tests/baseline_images/test_bbox_tight/bbox_inches_tight_suptile_legend.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0b2bd88dbcd21c110cb0e93817a38165d4193dee GIT binary patch literal 12421 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 literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/baseline_images/test_bbox_tight/bbox_inches_tight_suptile_legend.png b/lib/matplotlib/tests/baseline_images/test_bbox_tight/bbox_inches_tight_suptile_legend.png new file mode 100644 index 0000000000000000000000000000000000000000..0b25e78790c8da0aec1c1aea923894262d30118e GIT binary patch literal 33388 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 CDr1EJ literal 0 HcmV?d00001 diff --git a/lib/matplotlib/tests/baseline_images/test_bbox_tight/bbox_inches_tight_suptile_legend.svg b/lib/matplotlib/tests/baseline_images/test_bbox_tight/bbox_inches_tight_suptile_legend.svg new file mode 100644 index 000000000000..655cd238927a --- /dev/null +++ b/lib/matplotlib/tests/baseline_images/test_bbox_tight/bbox_inches_tight_suptile_legend.svg @@ -0,0 +1,1193 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/test_bbox_tight.py b/lib/matplotlib/tests/test_bbox_tight.py index d85a69fe3d7d..0b6ce233c061 100644 --- a/lib/matplotlib/tests/test_bbox_tight.py +++ b/lib/matplotlib/tests/test_bbox_tight.py @@ -1,6 +1,9 @@ from matplotlib import rcParams, rcParamsDefault from matplotlib.testing.decorators import image_comparison import matplotlib.pyplot as plt +import matplotlib.path as mpath +import matplotlib.patches as mpatches +from matplotlib.ticker import FuncFormatter import numpy as np @image_comparison(baseline_images=['bbox_inches_tight'], remove_text=True, @@ -36,6 +39,48 @@ def test_bbox_inches_tight(): rowLabels=rowLabels, colLabels=colLabels, loc='bottom') + +@image_comparison(baseline_images=['bbox_inches_tight_suptile_legend'], + remove_text=False, savefig_kwarg={'bbox_inches': 'tight'}) +def test_bbox_inches_tight_suptile_legend(): + plt.plot(range(10), label='a straight line') + plt.legend(bbox_to_anchor=(0.9, 1), loc=2, ) + plt.title('Axis title') + plt.suptitle('Figure title') + + # put an extra long y tick on to see that the bbox is accounted for + def y_formatter(y, pos): + if int(y) == 4: + return 'The number 4' + else: + return str(y) + plt.gca().yaxis.set_major_formatter(FuncFormatter(y_formatter)) + + plt.xlabel('X axis') + + +@image_comparison(baseline_images=['bbox_inches_tight_clipping'], + remove_text=True, savefig_kwarg={'bbox_inches': 'tight'}) +def test_bbox_inches_tight_clipping(): + # tests bbox clipping on scatter points, and path clipping on a patch + # to generate an appropriately tight bbox + plt.scatter(range(10), range(10)) + ax = plt.gca() + ax.set_xlim([0, 5]) + ax.set_ylim([0, 5]) + + # make a massive rectangle and clip it with a path + patch = mpatches.Rectangle([-50, -50], 100, 100, + transform=ax.transData, + facecolor='blue', alpha=0.5) + + path = mpath.Path.unit_regular_star(5) + path.vertices = path.vertices.copy() + path.vertices *= 0.25 + patch.set_clip_path(path, transform=ax.transAxes) + plt.gcf().artists.append(patch) + + if __name__ == '__main__': import nose nose.runmodule(argv=['-s', '--with-doctest'], exit=False) diff --git a/lib/matplotlib/tests/test_transforms.py b/lib/matplotlib/tests/test_transforms.py index bc8d5b93bd6b..1790c04ee9f8 100644 --- a/lib/matplotlib/tests/test_transforms.py +++ b/lib/matplotlib/tests/test_transforms.py @@ -444,6 +444,32 @@ def test_line_extents_for_non_affine_transData(self): expeted_data_lim) +def test_bbox_intersection(): + bbox_from_ext = mtrans.Bbox.from_extents + inter = mtrans.Bbox.intersection + + from numpy.testing import assert_array_equal as assert_a_equal + def assert_bbox_eq(bbox1, bbox2): + assert_a_equal(bbox1.bounds, bbox2.bounds) + + r1 = bbox_from_ext(0, 0, 1, 1) + r2 = bbox_from_ext(0.5, 0.5, 1.5, 1.5) + r3 = bbox_from_ext(0.5, 0, 0.75, 0.75) + r4 = bbox_from_ext(0.5, 1.5, 1, 2.5) + r5 = bbox_from_ext(1, 1, 2, 2) + + # self intersection -> no change + assert_bbox_eq(inter(r1, r1), r1) + # simple intersection + assert_bbox_eq(inter(r1, r2), bbox_from_ext(0.5, 0.5, 1, 1)) + # r3 contains r2 + assert_bbox_eq(inter(r1, r3), r3) + # no intersection + assert_equal(inter(r1, r4), None) + # single point + assert_bbox_eq(inter(r1, r5), bbox_from_ext(1, 1, 1, 1)) + + if __name__=='__main__': import nose nose.runmodule(argv=['-s','--with-doctest'], exit=False) diff --git a/lib/matplotlib/transforms.py b/lib/matplotlib/transforms.py index a3c3574eef1a..c95285cb11b0 100644 --- a/lib/matplotlib/transforms.py +++ b/lib/matplotlib/transforms.py @@ -732,6 +732,31 @@ def union(bboxes): return Bbox.from_extents(x0, y0, x1, y1) + @staticmethod + def intersection(bbox1, bbox2): + """ + Return the intersection of the two bboxes or None + if they do not intersect. + + Implements the algorithm described at: + + http://www.tekpool.com/node/2687 + + """ + intersects = not (bbox2.xmin > bbox1.xmax or + bbox2.xmax < bbox1.xmin or + bbox2.ymin > bbox1.ymax or + bbox2.ymax < bbox1.ymin) + + if intersects: + x0 = max([bbox1.xmin, bbox2.xmin]) + x1 = min([bbox1.xmax, bbox2.xmax]) + y0 = max([bbox1.ymin, bbox2.ymin]) + y1 = min([bbox1.ymax, bbox2.ymax]) + return Bbox.from_extents(x0, y0, x1, y1) + + return None + class Bbox(BboxBase): """ From 6569ca7bb371f1b070eedf026fbf71a55de07760 Mon Sep 17 00:00:00 2001 From: Phil Elson Date: Wed, 13 Mar 2013 14:04:00 +0000 Subject: [PATCH 2/2] Review actions. --- doc/users/whats_new.rst | 7 +++++++ lib/matplotlib/backend_bases.py | 2 -- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/users/whats_new.rst b/doc/users/whats_new.rst index 52573d38f554..2ac0a307f368 100644 --- a/doc/users/whats_new.rst +++ b/doc/users/whats_new.rst @@ -40,6 +40,13 @@ They may be symmetric or weighted. .. plot:: mpl_examples/pylab_examples/stackplot_demo2.py +Improved ``bbox_inches="tight"`` functionality +---------------------------------------------- +Passing ``bbox_inches="tight"`` through to :func:`plt.save` now takes into account +*all* artists on a figure - this was previously not the case and led to several +corner cases which did not function as expected. + + Remember save directory ----------------------- Martin Spacek made the save figure dialog remember the last directory saved diff --git a/lib/matplotlib/backend_bases.py b/lib/matplotlib/backend_bases.py index d639fb1b71db..4d3df1f385d5 100644 --- a/lib/matplotlib/backend_bases.py +++ b/lib/matplotlib/backend_bases.py @@ -2099,8 +2099,6 @@ def print_figure(self, filename, dpi=None, facecolor='w', edgecolor='w', bbox_filtered = [] for a in bbox_artists: bbox = a.get_window_extent(renderer) - # print('{0:40} - {1.width:5}, {1.height:5} ' - # '{1}'.format(type(a), bbox)) if a.get_clip_on(): clip_box = a.get_clip_box() if clip_box is not None: