From 10a0c8fac958e58332f896dcfdad911bddd5d6dd Mon Sep 17 00:00:00 2001 From: Bruno Beltran Date: Mon, 19 Oct 2020 10:41:42 -0700 Subject: [PATCH 1/3] BF: text not "draw"n shouldn't count for tightbbox --- lib/matplotlib/tests/test_tightlayout.py | 9 ++++++--- lib/matplotlib/text.py | 6 +++--- lib/matplotlib/tight_layout.py | 13 +++++++++++-- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/lib/matplotlib/tests/test_tightlayout.py b/lib/matplotlib/tests/test_tightlayout.py index 96c478de5768..23d363b5083b 100644 --- a/lib/matplotlib/tests/test_tightlayout.py +++ b/lib/matplotlib/tests/test_tightlayout.py @@ -288,13 +288,16 @@ def test_badsubplotgrid(): def test_collapsed(): - # test that if a call to tight_layout will collapses the axes that - # it does not get applied: + # test that if the amount of space required to make all the axes + # decorations fit would mean that the actual Axes would end up with size + # zero (i.e. margins add up to more than the available width) that a call + # to tight_layout will not get applied: fig, ax = plt.subplots(tight_layout=True) ax.set_xlim([0, 1]) ax.set_ylim([0, 1]) - ax.annotate('BIG LONG STRING', xy=(1.25, 2), xytext=(10.5, 1.75),) + ax.annotate('BIG LONG STRING', xy=(1.25, 2), xytext=(10.5, 1.75), + annotation_clip=False) p1 = ax.get_position() with pytest.warns(UserWarning): plt.tight_layout() diff --git a/lib/matplotlib/text.py b/lib/matplotlib/text.py index dc7824f3204d..910f437972aa 100644 --- a/lib/matplotlib/text.py +++ b/lib/matplotlib/text.py @@ -874,7 +874,7 @@ def get_window_extent(self, renderer=None, dpi=None): """ #return _unit_box if not self.get_visible(): - return Bbox.unit() + return Bbox.null() if dpi is None: dpi = self.figure.dpi if self.get_text() == '': @@ -1958,8 +1958,8 @@ def get_window_extent(self, renderer=None): """ # This block is the same as in Text.get_window_extent, but we need to # set the renderer before calling update_positions(). - if not self.get_visible(): - return Bbox.unit() + if not self.get_visible() or not self._check_xy(renderer): + return Bbox.null() if renderer is not None: self._renderer = renderer if self._renderer is None: diff --git a/lib/matplotlib/tight_layout.py b/lib/matplotlib/tight_layout.py index df55005047f9..0716d53a0ad9 100644 --- a/lib/matplotlib/tight_layout.py +++ b/lib/matplotlib/tight_layout.py @@ -68,8 +68,17 @@ def auto_adjust_subplotpars( if ax_bbox_list is None: ax_bbox_list = [ - Bbox.union([ax.get_position(original=True) for ax in subplots]) - for subplots in subplot_list] + [ax.get_position(original=True) for ax in subplots] + for subplots in subplot_list + ] + ax_bbox_list = [ + Bbox.union([ + b for b in bbox_list + if np.isfinite(b.width) and np.isfinite(b.height) + and (b.width != 0 or b.height != 0) + ]) + for bbox_list in ax_bbox_list + ] for subplots, ax_bbox, (num1, num2) in zip(subplot_list, ax_bbox_list, From 062d54a152d4d8b17de07139c1d72947c3d9b8ab Mon Sep 17 00:00:00 2001 From: Bruno Beltran Date: Mon, 19 Oct 2020 10:41:42 -0700 Subject: [PATCH 2/3] Text should take up a pixel of window extent when invisible --- lib/matplotlib/text.py | 10 ++++++++-- lib/matplotlib/tight_layout.py | 13 ++----------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/lib/matplotlib/text.py b/lib/matplotlib/text.py index 910f437972aa..6dc50b9f2dac 100644 --- a/lib/matplotlib/text.py +++ b/lib/matplotlib/text.py @@ -874,7 +874,7 @@ def get_window_extent(self, renderer=None, dpi=None): """ #return _unit_box if not self.get_visible(): - return Bbox.null() + return Bbox.unit() if dpi is None: dpi = self.figure.dpi if self.get_text() == '': @@ -1959,7 +1959,7 @@ def get_window_extent(self, renderer=None): # This block is the same as in Text.get_window_extent, but we need to # set the renderer before calling update_positions(). if not self.get_visible() or not self._check_xy(renderer): - return Bbox.null() + return Bbox.unit() if renderer is not None: self._renderer = renderer if self._renderer is None: @@ -1977,5 +1977,11 @@ def get_window_extent(self, renderer=None): return Bbox.union(bboxes) + def get_tightbbox(self, renderer): + # docstring inherited + if not self._check_xy(renderer): + return Bbox.null() + return super().get_tightbbox(renderer) + docstring.interpd.update(Annotation=Annotation.__init__.__doc__) diff --git a/lib/matplotlib/tight_layout.py b/lib/matplotlib/tight_layout.py index 0716d53a0ad9..df55005047f9 100644 --- a/lib/matplotlib/tight_layout.py +++ b/lib/matplotlib/tight_layout.py @@ -68,17 +68,8 @@ def auto_adjust_subplotpars( if ax_bbox_list is None: ax_bbox_list = [ - [ax.get_position(original=True) for ax in subplots] - for subplots in subplot_list - ] - ax_bbox_list = [ - Bbox.union([ - b for b in bbox_list - if np.isfinite(b.width) and np.isfinite(b.height) - and (b.width != 0 or b.height != 0) - ]) - for bbox_list in ax_bbox_list - ] + Bbox.union([ax.get_position(original=True) for ax in subplots]) + for subplots in subplot_list] for subplots, ax_bbox, (num1, num2) in zip(subplot_list, ax_bbox_list, From 0d1f34338c5aeb409fcc9a009051f9f3bc8c4997 Mon Sep 17 00:00:00 2001 From: Bruno Beltran Date: Tue, 20 Oct 2020 13:30:06 -0700 Subject: [PATCH 3/3] DOC: annotation tightbbox API change --- doc/api/next_api_changes/behavior/18772-BGB.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 doc/api/next_api_changes/behavior/18772-BGB.rst diff --git a/doc/api/next_api_changes/behavior/18772-BGB.rst b/doc/api/next_api_changes/behavior/18772-BGB.rst new file mode 100644 index 000000000000..bf1536c5494b --- /dev/null +++ b/doc/api/next_api_changes/behavior/18772-BGB.rst @@ -0,0 +1,12 @@ +Annotations with ``annotation_clip`` no longer affect ``tight_layout`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Previously, `.text.Annotation.get_tightbbox` always returned the full +`.text.Annotation.get_window_extent` of the object, independent of the value +of ``annotation_clip``. `.text.Annotation.get_tightbbox` now correctly takes +this extra clipping box into account, meaning that `~.text.Annotation`\s that +are not drawn because of ``annotation_clip`` will not count towards the axes +bounding box calculations, such as those done by `~.pyplot.tight_layout`. + +This is now consistent with the API described in `~.artist.Artist`, which +specifies that ``get_window_extent`` should return the full extents and +``get_tightbbox`` should "account for any clipping".