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". 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..6dc50b9f2dac 100644 --- a/lib/matplotlib/text.py +++ b/lib/matplotlib/text.py @@ -1958,7 +1958,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(): + if not self.get_visible() or not self._check_xy(renderer): return Bbox.unit() if renderer is not None: self._renderer = renderer @@ -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__)