Skip to content

Commit cfc01ce

Browse files
authored
Merge pull request #12285 from jklymak/fix-dont-apply-tight-layout-if-collapsed
FIX: Don't apply tight_layout if axes collapse
2 parents 52b7d4e + a58ce76 commit cfc01ce

File tree

5 files changed

+49
-13
lines changed

5 files changed

+49
-13
lines changed

doc/api/api_changes.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ This pages lists API changes for the most recent version of Matplotlib.
3636
next_api_changes/*
3737

3838

39+
API Changes for 3.0.1
40+
=====================
41+
42+
`.tight_layout.auto_adjust_subplotpars` can return ``None`` now if the new
43+
subplotparams will collapse axes to zero width or height. This prevents
44+
``tight_layout`` from being executed. Similarly
45+
`.tight_layout.get_tight_layout_figure` will return None.
46+
3947
API Changes for 3.0.0
4048
=====================
4149

lib/matplotlib/figure.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2390,7 +2390,8 @@ def tight_layout(self, renderer=None, pad=1.08, h_pad=None, w_pad=None,
23902390
kwargs = get_tight_layout_figure(
23912391
self, self.axes, subplotspec_list, renderer,
23922392
pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)
2393-
self.subplots_adjust(**kwargs)
2393+
if kwargs:
2394+
self.subplots_adjust(**kwargs)
23942395

23952396
def align_xlabels(self, axs=None):
23962397
"""

lib/matplotlib/gridspec.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,8 @@ def tight_layout(self, figure, renderer=None,
341341
kwargs = tight_layout.get_tight_layout_figure(
342342
figure, figure.axes, subplotspec_list, renderer,
343343
pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)
344-
self.update(**kwargs)
344+
if kwargs:
345+
self.update(**kwargs)
345346

346347

347348
class GridSpecFromSubplotSpec(GridSpecBase):

lib/matplotlib/tests/test_tightlayout.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,3 +316,19 @@ def test_badsubplotgrid():
316316
with warnings.catch_warnings(record=True) as w:
317317
plt.tight_layout()
318318
assert len(w) == 1
319+
320+
321+
def test_collapsed():
322+
# test that if a call to tight_layout will collapes the axes that
323+
# it does not get applied:
324+
fig, ax = plt.subplots(tight_layout=True)
325+
ax.set_xlim([0, 1])
326+
ax.set_ylim([0, 1])
327+
328+
ax.annotate('BIG LONG STRING', xy=(1.25, 2), xytext=(10.5, 1.75),)
329+
p1 = ax.get_position()
330+
with warnings.catch_warnings(record=True) as w:
331+
plt.tight_layout()
332+
p2 = ax.get_position()
333+
assert p1.width == p2.width
334+
assert len(w) == 1

lib/matplotlib/tight_layout.py

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ def auto_adjust_subplotpars(
3838
fig, renderer, nrows_ncols, num1num2_list, subplot_list,
3939
ax_bbox_list=None, pad=1.08, h_pad=None, w_pad=None, rect=None):
4040
"""
41-
Return a dict of subplot parameters to adjust spacing between subplots.
41+
Return a dict of subplot parameters to adjust spacing between subplots
42+
or ``None`` if resulting axes would have zero height or width.
4243
4344
Note that this function ignores geometry information of subplot
4445
itself, but uses what is given by the *nrows_ncols* and *num1num2_list*
@@ -172,15 +173,15 @@ def auto_adjust_subplotpars(
172173
margin_bottom += pad_inches / fig_height_inch
173174

174175
if margin_left + margin_right >= 1:
175-
margin_left = 0.4999
176-
margin_right = 0.4999
177-
warnings.warn('The left and right margins cannot be made large '
176+
warnings.warn('Tight layout not applied. The left and right margins '
177+
'cannot be made large '
178178
'enough to accommodate all axes decorations. ')
179+
return None
179180
if margin_bottom + margin_top >= 1:
180-
margin_bottom = 0.4999
181-
margin_top = 0.4999
182-
warnings.warn('The bottom and top margins cannot be made large '
181+
warnings.warn('Tight layout not applied. '
182+
'The bottom and top margins cannot be made large '
183183
'enough to accommodate all axes decorations. ')
184+
return None
184185

185186
kwargs = dict(left=margin_left,
186187
right=1 - margin_right,
@@ -195,9 +196,10 @@ def auto_adjust_subplotpars(
195196
# axes widths:
196197
h_axes = (1 - margin_right - margin_left - hspace * (cols - 1)) / cols
197198
if h_axes < 0:
198-
warnings.warn('tight_layout cannot make axes width small enough '
199+
warnings.warn('Tight layout not applied. '
200+
'tight_layout cannot make axes width small enough '
199201
'to accommodate all axes decorations')
200-
kwargs["wspace"] = 0.5
202+
return None
201203
else:
202204
kwargs["wspace"] = hspace / h_axes
203205

@@ -206,9 +208,10 @@ def auto_adjust_subplotpars(
206208
+ vpad_inches / fig_height_inch)
207209
v_axes = (1 - margin_top - margin_bottom - vspace * (rows - 1)) / rows
208210
if v_axes < 0:
209-
warnings.warn('tight_layout cannot make axes height small enough '
211+
warnings.warn('Tight layout not applied. '
212+
'tight_layout cannot make axes height small enough '
210213
'to accommodate all axes decorations')
211-
kwargs["hspace"] = 0.5
214+
return None
212215
else:
213216
kwargs["hspace"] = vspace / v_axes
214217

@@ -287,6 +290,13 @@ def get_tight_layout_figure(fig, axes_list, subplotspec_list, renderer,
287290
(left, bottom, right, top) rectangle in normalized figure coordinates
288291
that the whole subplots area (including labels) will fit into.
289292
Defaults to using the entire figure.
293+
294+
Returns
295+
-------
296+
subplotspec or None
297+
subplotspec kwargs to be passed to `.Figure.subplots_adjust` or
298+
None if tight_layout could not be accomplished.
299+
290300
"""
291301

292302
subplot_list = []

0 commit comments

Comments
 (0)