Skip to content

Commit 8864491

Browse files
authored
Merge pull request matplotlib#20094 from anntzer/aass
Switch _auto_adjust_subplotpars to take rowspan/colspan as input.
2 parents 46feb6e + 3c3177d commit 8864491

File tree

1 file changed

+57
-36
lines changed

1 file changed

+57
-36
lines changed

lib/matplotlib/tight_layout.py

Lines changed: 57 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111

1212
import numpy as np
1313

14-
from matplotlib import _api, docstring, rcParams
14+
from matplotlib import _api, rcParams
1515
from matplotlib.font_manager import FontProperties
1616
from matplotlib.transforms import TransformedBbox, Bbox
1717

1818

1919
def _auto_adjust_subplotpars(
20-
fig, renderer, nrows_ncols, num1num2_list, subplot_list,
20+
fig, renderer, shape, span_pairs, subplot_list,
2121
ax_bbox_list=None, pad=1.08, h_pad=None, w_pad=None, rect=None):
2222
"""
2323
Return a dict of subplot parameters to adjust spacing between subplots
@@ -30,10 +30,10 @@ def _auto_adjust_subplotpars(
3030
3131
Parameters
3232
----------
33-
nrows_ncols : tuple[int, int]
34-
Number of rows and number of columns of the grid.
35-
num1num2_list : list[int]
36-
List of numbers specifying the area occupied by the subplot
33+
shape : tuple[int, int]
34+
Number of rows and columns of the grid.
35+
span_pairs : list[tuple[slice, slice]]
36+
List of rowspans and colspans occupied by each subplot.
3737
subplot_list : list of subplots
3838
List of subplots that will be used to calculate optimal subplot_params.
3939
pad : float
@@ -45,15 +45,15 @@ def _auto_adjust_subplotpars(
4545
rect : tuple[float, float, float, float]
4646
[left, bottom, right, top] in normalized (0, 1) figure coordinates.
4747
"""
48-
rows, cols = nrows_ncols
48+
rows, cols = shape
4949

5050
font_size_inches = (
5151
FontProperties(size=rcParams["font.size"]).get_size_in_points() / 72)
5252
pad_inches = pad * font_size_inches
5353
vpad_inches = h_pad * font_size_inches if h_pad is not None else pad_inches
5454
hpad_inches = w_pad * font_size_inches if w_pad is not None else pad_inches
5555

56-
if len(num1num2_list) != len(subplot_list) or len(subplot_list) == 0:
56+
if len(span_pairs) != len(subplot_list) or len(subplot_list) == 0:
5757
raise ValueError
5858

5959
if rect is None:
@@ -71,9 +71,8 @@ def _auto_adjust_subplotpars(
7171
Bbox.union([ax.get_position(original=True) for ax in subplots])
7272
for subplots in subplot_list]
7373

74-
for subplots, ax_bbox, (num1, num2) in zip(subplot_list,
75-
ax_bbox_list,
76-
num1num2_list):
74+
for subplots, ax_bbox, (rowspan, colspan) in zip(
75+
subplot_list, ax_bbox_list, span_pairs):
7776
if all(not ax.get_visible() for ax in subplots):
7877
continue
7978

@@ -89,15 +88,10 @@ def _auto_adjust_subplotpars(
8988
tight_bbox = TransformedBbox(tight_bbox_raw,
9089
fig.transFigure.inverted())
9190

92-
row1, col1 = divmod(num1, cols)
93-
row2, col2 = divmod(num2, cols)
94-
95-
for row_i in range(row1, row2 + 1):
96-
hspaces[row_i, col1] += ax_bbox.xmin - tight_bbox.xmin # left
97-
hspaces[row_i, col2 + 1] += tight_bbox.xmax - ax_bbox.xmax # right
98-
for col_i in range(col1, col2 + 1):
99-
vspaces[row1, col_i] += tight_bbox.ymax - ax_bbox.ymax # top
100-
vspaces[row2 + 1, col_i] += ax_bbox.ymin - tight_bbox.ymin # bot.
91+
hspaces[rowspan, colspan.start] += ax_bbox.xmin - tight_bbox.xmin # l
92+
hspaces[rowspan, colspan.stop] += tight_bbox.xmax - ax_bbox.xmax # r
93+
vspaces[rowspan.start, colspan] += tight_bbox.ymax - ax_bbox.ymax # t
94+
vspaces[rowspan.stop, colspan] += ax_bbox.ymin - tight_bbox.ymin # b
10195

10296
fig_width_inch, fig_height_inch = fig.get_size_inches()
10397

@@ -173,12 +167,42 @@ def _auto_adjust_subplotpars(
173167

174168

175169
@_api.deprecated("3.5")
176-
@docstring.copy(_auto_adjust_subplotpars)
177170
def auto_adjust_subplotpars(
178171
fig, renderer, nrows_ncols, num1num2_list, subplot_list,
179172
ax_bbox_list=None, pad=1.08, h_pad=None, w_pad=None, rect=None):
180-
num1num2_list = [
181-
(n1, n1 if n2 is None else n2) for n1, n2 in num1num2_list]
173+
"""
174+
Return a dict of subplot parameters to adjust spacing between subplots
175+
or ``None`` if resulting axes would have zero height or width.
176+
177+
Note that this function ignores geometry information of subplot
178+
itself, but uses what is given by the *nrows_ncols* and *num1num2_list*
179+
parameters. Also, the results could be incorrect if some subplots have
180+
``adjustable=datalim``.
181+
182+
Parameters
183+
----------
184+
nrows_ncols : tuple[int, int]
185+
Number of rows and number of columns of the grid.
186+
num1num2_list : list[tuple[int, int]]
187+
List of numbers specifying the area occupied by the subplot
188+
subplot_list : list of subplots
189+
List of subplots that will be used to calculate optimal subplot_params.
190+
pad : float
191+
Padding between the figure edge and the edges of subplots, as a
192+
fraction of the font size.
193+
h_pad, w_pad : float
194+
Padding (height/width) between edges of adjacent subplots, as a
195+
fraction of the font size. Defaults to *pad*.
196+
rect : tuple[float, float, float, float]
197+
[left, bottom, right, top] in normalized (0, 1) figure coordinates.
198+
"""
199+
nrows, ncols = nrows_ncols
200+
span_pairs = []
201+
for n1, n2 in num1num2_list:
202+
if n2 is None:
203+
n2 = n1
204+
span_pairs.append((slice(n1 // ncols, n2 // ncols + 1),
205+
slice(n1 % ncols, n2 % ncols + 1)))
182206
return _auto_adjust_subplotpars(
183207
fig, renderer, nrows_ncols, num1num2_list, subplot_list,
184208
ax_bbox_list, pad, h_pad, w_pad, rect)
@@ -292,9 +316,9 @@ def get_tight_layout_figure(fig, axes_list, subplotspec_list, renderer,
292316
max_nrows = max(nrows_list)
293317
max_ncols = max(ncols_list)
294318

295-
num1num2_list = []
296-
for subplotspec in subplotspec_list2:
297-
rows, cols, num1, num2 = subplotspec.get_geometry()
319+
span_pairs = []
320+
for ss in subplotspec_list2:
321+
rows, cols = ss.get_gridspec().get_geometry()
298322
div_row, mod_row = divmod(max_nrows, rows)
299323
div_col, mod_col = divmod(max_ncols, cols)
300324
if mod_row != 0:
@@ -308,16 +332,13 @@ def get_tight_layout_figure(fig, axes_list, subplotspec_list, renderer,
308332
'multiples of one another.')
309333
return {}
310334

311-
row1, col1 = divmod(num1, cols)
312-
row2, col2 = divmod(num2, cols)
313-
314-
num1num2_list.append((row1 * div_row * max_ncols + col1 * div_col,
315-
((row2 + 1) * div_row - 1) * max_ncols +
316-
(col2 + 1) * div_col - 1))
335+
span_pairs.append((
336+
slice(ss.rowspan.start * div_row, ss.rowspan.stop * div_row),
337+
slice(ss.colspan.start * div_col, ss.colspan.stop * div_col)))
317338

318339
kwargs = _auto_adjust_subplotpars(fig, renderer,
319-
nrows_ncols=(max_nrows, max_ncols),
320-
num1num2_list=num1num2_list,
340+
shape=(max_nrows, max_ncols),
341+
span_pairs=span_pairs,
321342
subplot_list=subplot_list,
322343
ax_bbox_list=ax_bbox_list,
323344
pad=pad, h_pad=h_pad, w_pad=w_pad)
@@ -343,8 +364,8 @@ def get_tight_layout_figure(fig, axes_list, subplotspec_list, renderer,
343364
top -= (1 - kwargs["top"])
344365

345366
kwargs = _auto_adjust_subplotpars(fig, renderer,
346-
nrows_ncols=(max_nrows, max_ncols),
347-
num1num2_list=num1num2_list,
367+
shape=(max_nrows, max_ncols),
368+
span_pairs=span_pairs,
348369
subplot_list=subplot_list,
349370
ax_bbox_list=ax_bbox_list,
350371
pad=pad, h_pad=h_pad, w_pad=w_pad,

0 commit comments

Comments
 (0)