From 72c80f46a33daa7f975770692b202ee7e3cb05b3 Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Tue, 25 Sep 2018 12:58:20 -0700 Subject: [PATCH 1/4] FIX: Don't apply tight_layout if axes collapse --- lib/matplotlib/figure.py | 3 ++- lib/matplotlib/gridspec.py | 3 ++- lib/matplotlib/tight_layout.py | 22 ++++++++++++---------- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/lib/matplotlib/figure.py b/lib/matplotlib/figure.py index f5f62466075c..a8d96a4d2e58 100644 --- a/lib/matplotlib/figure.py +++ b/lib/matplotlib/figure.py @@ -2390,7 +2390,8 @@ def tight_layout(self, renderer=None, pad=1.08, h_pad=None, w_pad=None, kwargs = get_tight_layout_figure( self, self.axes, subplotspec_list, renderer, pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect) - self.subplots_adjust(**kwargs) + if kwargs: + self.subplots_adjust(**kwargs) def align_xlabels(self, axs=None): """ diff --git a/lib/matplotlib/gridspec.py b/lib/matplotlib/gridspec.py index 7e2bd1fae674..ac2b77ddbe1d 100644 --- a/lib/matplotlib/gridspec.py +++ b/lib/matplotlib/gridspec.py @@ -341,7 +341,8 @@ def tight_layout(self, figure, renderer=None, kwargs = tight_layout.get_tight_layout_figure( figure, figure.axes, subplotspec_list, renderer, pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect) - self.update(**kwargs) + if kwargs: + self.update(**kwargs) class GridSpecFromSubplotSpec(GridSpecBase): diff --git a/lib/matplotlib/tight_layout.py b/lib/matplotlib/tight_layout.py index 344413cc9b7e..8c3483546357 100644 --- a/lib/matplotlib/tight_layout.py +++ b/lib/matplotlib/tight_layout.py @@ -172,15 +172,15 @@ def auto_adjust_subplotpars( margin_bottom += pad_inches / fig_height_inch if margin_left + margin_right >= 1: - margin_left = 0.4999 - margin_right = 0.4999 - warnings.warn('The left and right margins cannot be made large ' + warnings.warn('Tight layout not applied. The left and right margins ' + 'cannot be made large ' 'enough to accommodate all axes decorations. ') + return None if margin_bottom + margin_top >= 1: - margin_bottom = 0.4999 - margin_top = 0.4999 - warnings.warn('The bottom and top margins cannot be made large ' + warnings.warn('Tight layout not applied. ' + 'The bottom and top margins cannot be made large ' 'enough to accommodate all axes decorations. ') + return None kwargs = dict(left=margin_left, right=1 - margin_right, @@ -195,9 +195,10 @@ def auto_adjust_subplotpars( # axes widths: h_axes = (1 - margin_right - margin_left - hspace * (cols - 1)) / cols if h_axes < 0: - warnings.warn('tight_layout cannot make axes width small enough ' + warnings.warn('Tight layout not applied. ' + 'tight_layout cannot make axes width small enough ' 'to accommodate all axes decorations') - kwargs["wspace"] = 0.5 + return None else: kwargs["wspace"] = hspace / h_axes @@ -206,9 +207,10 @@ def auto_adjust_subplotpars( + vpad_inches / fig_height_inch) v_axes = (1 - margin_top - margin_bottom - vspace * (rows - 1)) / rows if v_axes < 0: - warnings.warn('tight_layout cannot make axes height small enough ' + warnings.warn('Tight layout not applied. ' + 'tight_layout cannot make axes height small enough ' 'to accommodate all axes decorations') - kwargs["hspace"] = 0.5 + return None else: kwargs["hspace"] = vspace / v_axes From 5919ec833b9acf55a88b1bc48021cecb6dca3b63 Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Wed, 26 Sep 2018 21:07:56 -0700 Subject: [PATCH 2/4] DOC/TST Add API note and add test --- doc/api/api_changes.rst | 7 +++++++ lib/matplotlib/tests/test_tightlayout.py | 16 ++++++++++++++++ lib/matplotlib/tight_layout.py | 3 ++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/doc/api/api_changes.rst b/doc/api/api_changes.rst index 200d07c4f460..634cc369572b 100644 --- a/doc/api/api_changes.rst +++ b/doc/api/api_changes.rst @@ -33,6 +33,13 @@ This pages lists API changes for the most recent version of Matplotlib. next_api_changes/* +API Changes for 3.0.1 +===================== + +`.tight_layout.auto_adjust_subplotpars` can return ``None`` now if the new +subplotparams will collapse axes to zero width or height. This prevents +``tight_layout`` from being executed. + API Changes for 3.0.0 ===================== diff --git a/lib/matplotlib/tests/test_tightlayout.py b/lib/matplotlib/tests/test_tightlayout.py index 2d143c63d9c4..4d2fbb20980f 100644 --- a/lib/matplotlib/tests/test_tightlayout.py +++ b/lib/matplotlib/tests/test_tightlayout.py @@ -316,3 +316,19 @@ def test_badsubplotgrid(): with warnings.catch_warnings(record=True) as w: plt.tight_layout() assert len(w) == 1 + + +def test_collapsed(): + # test that if a call to tight_layout will collapes the axes that + # it does 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),) + p1 = ax.get_position() + with warnings.catch_warnings(record=True) as w: + plt.tight_layout() + p2 = ax.get_position() + assert p1.width == p2.width + assert len(w) == 1 diff --git a/lib/matplotlib/tight_layout.py b/lib/matplotlib/tight_layout.py index 8c3483546357..3a38cbcf8d81 100644 --- a/lib/matplotlib/tight_layout.py +++ b/lib/matplotlib/tight_layout.py @@ -38,7 +38,8 @@ def auto_adjust_subplotpars( fig, renderer, nrows_ncols, num1num2_list, subplot_list, ax_bbox_list=None, pad=1.08, h_pad=None, w_pad=None, rect=None): """ - Return a dict of subplot parameters to adjust spacing between subplots. + Return a dict of subplot parameters to adjust spacing between subplots + or ``None`` if resulting axes would have zero height or width. Note that this function ignores geometry information of subplot itself, but uses what is given by the *nrows_ncols* and *num1num2_list* From a687aaf8c56298674af7a9d7409505e4e8510e3b Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Sat, 13 Oct 2018 17:20:37 -0700 Subject: [PATCH 3/4] DOC: document return from get_tight_layout_figure --- doc/api/api_changes.rst | 3 ++- lib/matplotlib/tight_layout.py | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/doc/api/api_changes.rst b/doc/api/api_changes.rst index 634cc369572b..10f507599ab3 100644 --- a/doc/api/api_changes.rst +++ b/doc/api/api_changes.rst @@ -38,7 +38,8 @@ API Changes for 3.0.1 `.tight_layout.auto_adjust_subplotpars` can return ``None`` now if the new subplotparams will collapse axes to zero width or height. This prevents -``tight_layout`` from being executed. +``tight_layout`` from being executed. Similarly +`.tight_layout.get_tight_layout_figure` will return None. API Changes for 3.0.0 ===================== diff --git a/lib/matplotlib/tight_layout.py b/lib/matplotlib/tight_layout.py index 3a38cbcf8d81..aa42a957bb78 100644 --- a/lib/matplotlib/tight_layout.py +++ b/lib/matplotlib/tight_layout.py @@ -290,6 +290,13 @@ def get_tight_layout_figure(fig, axes_list, subplotspec_list, renderer, (left, bottom, right, top) rectangle in normalized figure coordinates that the whole subplots area (including labels) will fit into. Defaults to using the entire figure. + + Returns + ------- + subplotspec or None + subplotspec kwargs to be passed to `.Figure.subplots_adjust` or + None if tight_layout could not be accomplished. + """ subplot_list = [] From a58ce7655f11f69c8cfe0d37d79b166007091ddd Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Mon, 15 Oct 2018 14:20:50 -0700 Subject: [PATCH 4/4] DOC: document return from get_tight_layout_figure --- lib/matplotlib/tight_layout.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/matplotlib/tight_layout.py b/lib/matplotlib/tight_layout.py index aa42a957bb78..0b3b40e1cd98 100644 --- a/lib/matplotlib/tight_layout.py +++ b/lib/matplotlib/tight_layout.py @@ -295,7 +295,7 @@ def get_tight_layout_figure(fig, axes_list, subplotspec_list, renderer, ------- subplotspec or None subplotspec kwargs to be passed to `.Figure.subplots_adjust` or - None if tight_layout could not be accomplished. + None if tight_layout could not be accomplished. """