Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b33711b

Browse files
authored
Merge pull request #20144 from anntzer/tl
More tight_layout cleanups
2 parents e1d1095 + 6ad2818 commit b33711b

File tree

1 file changed

+37
-57
lines changed

1 file changed

+37
-57
lines changed

lib/matplotlib/tight_layout.py

Lines changed: 37 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,9 @@ def _auto_adjust_subplotpars(
2323
Return a dict of subplot parameters to adjust spacing between subplots
2424
or ``None`` if resulting axes would have zero height or width.
2525
26-
Note that this function ignores geometry information of subplot
27-
itself, but uses what is given by the *nrows_ncols* and *num1num2_list*
28-
parameters. Also, the results could be incorrect if some subplots have
29-
``adjustable=datalim``.
26+
Note that this function ignores geometry information of subplot itself, but
27+
uses what is given by the *shape* and *subplot_list* parameters. Also, the
28+
results could be incorrect if some subplots have ``adjustable=datalim``.
3029
3130
Parameters
3231
----------
@@ -47,11 +46,11 @@ def _auto_adjust_subplotpars(
4746
"""
4847
rows, cols = shape
4948

50-
font_size_inches = (
49+
font_size_inch = (
5150
FontProperties(size=rcParams["font.size"]).get_size_in_points() / 72)
52-
pad_inches = pad * font_size_inches
53-
vpad_inches = h_pad * font_size_inches if h_pad is not None else pad_inches
54-
hpad_inches = w_pad * font_size_inches if w_pad is not None else pad_inches
51+
pad_inch = pad * font_size_inch
52+
vpad_inch = h_pad * font_size_inch if h_pad is not None else pad_inch
53+
hpad_inch = w_pad * font_size_inch if w_pad is not None else pad_inch
5554

5655
if len(span_pairs) != len(subplot_list) or len(subplot_list) == 0:
5756
raise ValueError
@@ -98,42 +97,37 @@ def _auto_adjust_subplotpars(
9897
# margins can be negative for axes with aspect applied, so use max(, 0) to
9998
# make them nonnegative.
10099
if not margin_left:
101-
margin_left = (max(hspaces[:, 0].max(), 0)
102-
+ pad_inches / fig_width_inch)
100+
margin_left = max(hspaces[:, 0].max(), 0) + pad_inch/fig_width_inch
103101
suplabel = fig._supylabel
104102
if suplabel and suplabel.get_in_layout():
105103
rel_width = fig.transFigure.inverted().transform_bbox(
106104
suplabel.get_window_extent(renderer)).width
107-
margin_left += rel_width + pad_inches / fig_width_inch
108-
105+
margin_left += rel_width + pad_inch/fig_width_inch
109106
if not margin_right:
110-
margin_right = (max(hspaces[:, -1].max(), 0)
111-
+ pad_inches / fig_width_inch)
107+
margin_right = max(hspaces[:, -1].max(), 0) + pad_inch/fig_width_inch
112108
if not margin_top:
113-
margin_top = (max(vspaces[0, :].max(), 0)
114-
+ pad_inches / fig_height_inch)
109+
margin_top = max(vspaces[0, :].max(), 0) + pad_inch/fig_height_inch
115110
if fig._suptitle and fig._suptitle.get_in_layout():
116111
rel_height = fig.transFigure.inverted().transform_bbox(
117112
fig._suptitle.get_window_extent(renderer)).height
118-
margin_top += rel_height + pad_inches / fig_height_inch
113+
margin_top += rel_height + pad_inch/fig_height_inch
119114
if not margin_bottom:
120-
margin_bottom = (max(vspaces[-1, :].max(), 0)
121-
+ pad_inches / fig_height_inch)
115+
margin_bottom = max(vspaces[-1, :].max(), 0) + pad_inch/fig_height_inch
122116
suplabel = fig._supxlabel
123117
if suplabel and suplabel.get_in_layout():
124118
rel_height = fig.transFigure.inverted().transform_bbox(
125119
suplabel.get_window_extent(renderer)).height
126-
margin_bottom += rel_height + pad_inches / fig_height_inch
120+
margin_bottom += rel_height + pad_inch/fig_height_inch
127121

128122
if margin_left + margin_right >= 1:
129123
_api.warn_external('Tight layout not applied. The left and right '
130124
'margins cannot be made large enough to '
131-
'accommodate all axes decorations. ')
125+
'accommodate all axes decorations.')
132126
return None
133127
if margin_bottom + margin_top >= 1:
134128
_api.warn_external('Tight layout not applied. The bottom and top '
135129
'margins cannot be made large enough to '
136-
'accommodate all axes decorations. ')
130+
'accommodate all axes decorations.')
137131
return None
138132

139133
kwargs = dict(left=margin_left,
@@ -142,7 +136,7 @@ def _auto_adjust_subplotpars(
142136
top=1 - margin_top)
143137

144138
if cols > 1:
145-
hspace = hspaces[:, 1:-1].max() + hpad_inches / fig_width_inch
139+
hspace = hspaces[:, 1:-1].max() + hpad_inch / fig_width_inch
146140
# axes widths:
147141
h_axes = (1 - margin_right - margin_left - hspace * (cols - 1)) / cols
148142
if h_axes < 0:
@@ -153,12 +147,12 @@ def _auto_adjust_subplotpars(
153147
else:
154148
kwargs["wspace"] = hspace / h_axes
155149
if rows > 1:
156-
vspace = vspaces[1:-1, :].max() + vpad_inches / fig_height_inch
150+
vspace = vspaces[1:-1, :].max() + vpad_inch / fig_height_inch
157151
v_axes = (1 - margin_top - margin_bottom - vspace * (rows - 1)) / rows
158152
if v_axes < 0:
159153
_api.warn_external('Tight layout not applied. tight_layout '
160154
'cannot make axes height small enough to '
161-
'accommodate all axes decorations')
155+
'accommodate all axes decorations.')
162156
return None
163157
else:
164158
kwargs["hspace"] = vspace / v_axes
@@ -283,41 +277,28 @@ def get_tight_layout_figure(fig, axes_list, subplotspec_list, renderer,
283277
None if tight_layout could not be accomplished.
284278
"""
285279

286-
subplot_list = []
287-
nrows_list = []
288-
ncols_list = []
289-
ax_bbox_list = []
290-
291-
# Multiple axes can share same subplot_interface (e.g., axes_grid1); thus
292-
# we need to join them together.
293-
subplot_dict = {}
294-
295-
subplotspec_list2 = []
296-
297-
for ax, subplotspec in zip(axes_list, subplotspec_list):
298-
if subplotspec is None:
299-
continue
300-
301-
subplots = subplot_dict.setdefault(subplotspec, [])
302-
303-
if not subplots:
304-
myrows, mycols, _, _ = subplotspec.get_geometry()
305-
nrows_list.append(myrows)
306-
ncols_list.append(mycols)
307-
subplotspec_list2.append(subplotspec)
308-
subplot_list.append(subplots)
309-
ax_bbox_list.append(subplotspec.get_position(fig))
310-
311-
subplots.append(ax)
312-
313-
if len(nrows_list) == 0 or len(ncols_list) == 0:
280+
# Multiple axes can share same subplotspec (e.g., if using axes_grid1);
281+
# we need to group them together.
282+
ss_to_subplots = {ss: [] for ss in subplotspec_list}
283+
for ax, ss in zip(axes_list, subplotspec_list):
284+
ss_to_subplots[ss].append(ax)
285+
ss_to_subplots.pop(None, None) # Skip subplotspec == None.
286+
if not ss_to_subplots:
314287
return {}
288+
subplot_list = list(ss_to_subplots.values())
289+
ax_bbox_list = [ss.get_position(fig) for ss in ss_to_subplots]
315290

316-
max_nrows = max(nrows_list)
317-
max_ncols = max(ncols_list)
291+
max_nrows = max(ss.get_gridspec().nrows for ss in ss_to_subplots)
292+
max_ncols = max(ss.get_gridspec().ncols for ss in ss_to_subplots)
318293

319294
span_pairs = []
320-
for ss in subplotspec_list2:
295+
for ss in ss_to_subplots:
296+
# The intent here is to support axes from different gridspecs where
297+
# one's nrows (or ncols) is a multiple of the other (e.g. 2 and 4),
298+
# but this doesn't actually work because the computed wspace, in
299+
# relative-axes-height, corresponds to different physical spacings for
300+
# the 2-row grid and the 4-row grid. Still, this code is left, mostly
301+
# for backcompat.
321302
rows, cols = ss.get_gridspec().get_geometry()
322303
div_row, mod_row = divmod(max_nrows, rows)
323304
div_col, mod_col = divmod(max_ncols, cols)
@@ -331,7 +312,6 @@ def get_tight_layout_figure(fig, axes_list, subplotspec_list, renderer,
331312
'columns in subplot specifications must be '
332313
'multiples of one another.')
333314
return {}
334-
335315
span_pairs.append((
336316
slice(ss.rowspan.start * div_row, ss.rowspan.stop * div_row),
337317
slice(ss.colspan.start * div_col, ss.colspan.stop * div_col)))

0 commit comments

Comments
 (0)