From 0fe574ef6bfb913d9bd5b48616f1b24113783e56 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Fri, 1 May 2020 00:35:21 +0200 Subject: [PATCH 1/2] Make API of get_tightbbox more consistent between Axes and Axis. Instead of having Axes trying to figure out what direction to ignore, let the Axis handle that. This keeps the signature of get_tightbbox consistent between Axes and Axis. Also fix a typo bb_xaxis -> bb_yaxis. --- doc/api/api_changes_3.3/behaviour.rst | 8 +++----- lib/matplotlib/axes/_base.py | 11 +++++------ lib/matplotlib/axis.py | 25 +++++++++++++------------ 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/doc/api/api_changes_3.3/behaviour.rst b/doc/api/api_changes_3.3/behaviour.rst index b23b136f0d0e..0491e31372ff 100644 --- a/doc/api/api_changes_3.3/behaviour.rst +++ b/doc/api/api_changes_3.3/behaviour.rst @@ -229,11 +229,9 @@ x direction, making the axes smaller in the x-direction doesn't help. The behavior of both has been changed to ignore the width of the title and xlabel and the height of the ylabel in the layout logic. -This also means there is a new keyword argument for `.axes.Axes.get_tightbbox`: -``for_layout_only``, which defaults to *False*, but if *True* returns a -bounding box using the rules above. `.axis.Axis.get_tightbbox` gets an -``ignore_label`` keyword argument, which is *None* by default, but which can -also be 'x' or 'y'. +This also means there is a new keyword argument for `.axes.Axes.get_tightbbox` +and `.axis.Axis.get_tightbbox`: ``for_layout_only``, which defaults to *False*, +but if *True* returns a bounding box using the rules above. :rc:`savefig.facecolor` and :rc:`savefig.edgecolor` now default to "auto" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index 8f60cfeddf3a..77866c4e2909 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -4143,21 +4143,20 @@ def get_tightbbox(self, renderer, call_axes_locator=True, self.apply_aspect() if self.axison: - igl = 'x' if for_layout_only else None try: - bb_xaxis = self.xaxis.get_tightbbox(renderer, ignore_label=igl) + bb_xaxis = self.xaxis.get_tightbbox( + renderer, for_layout_only=for_layout_only) except TypeError: # in case downstream library has redefined axis: bb_xaxis = self.xaxis.get_tightbbox(renderer) if bb_xaxis: bb.append(bb_xaxis) - - igl = 'y' if for_layout_only else None try: - bb_yaxis = self.yaxis.get_tightbbox(renderer, ignore_label=igl) + bb_yaxis = self.yaxis.get_tightbbox( + renderer, for_layout_only=for_layout_only) except TypeError: # in case downstream library has redefined axis: - bb_xaxis = self.yaxis.get_tightbbox(renderer) + bb_yaxis = self.yaxis.get_tightbbox(renderer) if bb_yaxis: bb.append(bb_yaxis) self._update_title_position(renderer) diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index d56af88b64f6..448afa34e0c9 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -1079,15 +1079,15 @@ def _get_tick_bboxes(self, ticks, renderer): [tick.label2.get_window_extent(renderer) for tick in ticks if tick.label2.get_visible()]) - def get_tightbbox(self, renderer, *, ignore_label=None): + def get_tightbbox(self, renderer, *, for_layout_only=False): """ Return a bounding box that encloses the axis. It only accounts tick labels, axis label, and offsetText. - If ``ignore_label`` is 'x', then the width of the label is collapsed - to near zero. If 'y', then the height is collapsed to near zero. This - is for tight/constrained_layout to be able to ignore too-long labels - when doing their layout. + If *for_layout_only* is True, then the width of the label (if this + is an x-axis) or the height of the label (if this is a y-axis) is + collapsed to near zero. This allows tight/constrained_layout to ignore + too-long labels when doing their layout. """ if not self.get_visible(): return @@ -1114,14 +1114,15 @@ def get_tightbbox(self, renderer, *, ignore_label=None): if self.label.get_visible(): bb = self.label.get_window_extent(renderer) # for constrained/tight_layout, we want to ignore the label's - # width because the adjustments they make can't be improved. + # width/height because the adjustments they make can't be improved. # this code collapses the relevant direction - if ignore_label == 'x' and bb.width > 0: - bb.x0 = (bb.x0 + bb.x1) / 2 - 0.5 - bb.x1 = bb.x0 + 1.0 - elif ignore_label == 'y' and bb.height > 0: - bb.y0 = (bb.y0 + bb.y1) / 2 - 0.5 - bb.y1 = bb.y0 + 1.0 + if for_layout_only: + if self.axis_name == "x" and bb.width > 0: + bb.x0 = (bb.x0 + bb.x1) / 2 - 0.5 + bb.x1 = bb.x0 + 1.0 + if self.axis_name == "y" and bb.height > 0: + bb.y0 = (bb.y0 + bb.y1) / 2 - 0.5 + bb.y1 = bb.y0 + 1.0 bboxes.append(bb) bboxes = [b for b in bboxes if 0 < b.width < np.inf and 0 < b.height < np.inf] From d530e47b8665122ead89192e63cc1af5c0ee4914 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Fri, 8 May 2020 01:42:24 +0200 Subject: [PATCH 2/2] Only consider visible Axises in Axes tightbbox. --- lib/matplotlib/axes/_base.py | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index 77866c4e2909..dbf39c8f7636 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -4143,22 +4143,24 @@ def get_tightbbox(self, renderer, call_axes_locator=True, self.apply_aspect() if self.axison: - try: - bb_xaxis = self.xaxis.get_tightbbox( - renderer, for_layout_only=for_layout_only) - except TypeError: - # in case downstream library has redefined axis: - bb_xaxis = self.xaxis.get_tightbbox(renderer) - if bb_xaxis: - bb.append(bb_xaxis) - try: - bb_yaxis = self.yaxis.get_tightbbox( - renderer, for_layout_only=for_layout_only) - except TypeError: - # in case downstream library has redefined axis: - bb_yaxis = self.yaxis.get_tightbbox(renderer) - if bb_yaxis: - bb.append(bb_yaxis) + if self.xaxis.get_visible(): + try: + bb_xaxis = self.xaxis.get_tightbbox( + renderer, for_layout_only=for_layout_only) + except TypeError: + # in case downstream library has redefined axis: + bb_xaxis = self.xaxis.get_tightbbox(renderer) + if bb_xaxis: + bb.append(bb_xaxis) + if self.yaxis.get_visible(): + try: + bb_yaxis = self.yaxis.get_tightbbox( + renderer, for_layout_only=for_layout_only) + except TypeError: + # in case downstream library has redefined axis: + bb_yaxis = self.yaxis.get_tightbbox(renderer) + if bb_yaxis: + bb.append(bb_yaxis) self._update_title_position(renderer) axbbox = self.get_window_extent(renderer) bb.append(axbbox)