99for some cases (for example, left or right margin is affected by xlabel).
1010"""
1111
12+ import numpy as np
13+
1214from matplotlib import cbook , rcParams
1315from matplotlib .font_manager import FontProperties
1416from matplotlib .transforms import TransformedBbox , Bbox
1517
1618
17- def _get_left (tight_bbox , axes_bbox ):
18- return axes_bbox .xmin - tight_bbox .xmin
19-
20-
21- def _get_right (tight_bbox , axes_bbox ):
22- return tight_bbox .xmax - axes_bbox .xmax
23-
24-
25- def _get_bottom (tight_bbox , axes_bbox ):
26- return axes_bbox .ymin - tight_bbox .ymin
27-
28-
29- def _get_top (tight_bbox , axes_bbox ):
30- return tight_bbox .ymax - axes_bbox .ymax
31-
32-
3319def auto_adjust_subplotpars (
3420 fig , renderer , nrows_ncols , num1num2_list , subplot_list ,
3521 ax_bbox_list = None , pad = 1.08 , h_pad = None , w_pad = None , rect = None ):
@@ -64,15 +50,8 @@ def auto_adjust_subplotpars(
6450 font_size_inches = (
6551 FontProperties (size = rcParams ["font.size" ]).get_size_in_points () / 72 )
6652 pad_inches = pad * font_size_inches
67- if h_pad is not None :
68- vpad_inches = h_pad * font_size_inches
69- else :
70- vpad_inches = pad_inches
71-
72- if w_pad is not None :
73- hpad_inches = w_pad * font_size_inches
74- else :
75- hpad_inches = pad_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
7655
7756 if len (num1num2_list ) != len (subplot_list ) or len (subplot_list ) == 0 :
7857 raise ValueError
@@ -81,23 +60,15 @@ def auto_adjust_subplotpars(
8160 margin_left = margin_bottom = margin_right = margin_top = None
8261 else :
8362 margin_left , margin_bottom , _right , _top = rect
84- if _right :
85- margin_right = 1 - _right
86- else :
87- margin_right = None
88- if _top :
89- margin_top = 1 - _top
90- else :
91- margin_top = None
92-
93- vspaces = [[] for _ in range ((rows + 1 ) * cols )]
94- hspaces = [[] for _ in range (rows * (cols + 1 ))]
63+ margin_right = 1 - _right if _right else None
64+ margin_top = 1 - _top if _top else None
9565
96- union = Bbox .union
66+ vspaces = np .zeros ((rows + 1 , cols ))
67+ hspaces = np .zeros ((rows , cols + 1 ))
9768
9869 if ax_bbox_list is None :
9970 ax_bbox_list = [
100- union ([ax .get_position (original = True ) for ax in subplots ])
71+ Bbox . union ([ax .get_position (original = True ) for ax in subplots ])
10172 for subplots in subplot_list ]
10273
10374 for subplots , ax_bbox , (num1 , num2 ) in zip (subplot_list ,
@@ -106,66 +77,39 @@ def auto_adjust_subplotpars(
10677 if all (not ax .get_visible () for ax in subplots ):
10778 continue
10879
109- tight_bbox_raw = union ([ax . get_tightbbox ( renderer ) for ax in subplots
110- if ax .get_visible ()])
80+ tight_bbox_raw = Bbox . union ([
81+ ax . get_tightbbox ( renderer ) for ax in subplots if ax .get_visible ()])
11182 tight_bbox = TransformedBbox (tight_bbox_raw ,
11283 fig .transFigure .inverted ())
11384
11485 row1 , col1 = divmod (num1 , cols )
115-
11686 if num2 is None :
117- # left
118- hspaces [row1 * (cols + 1 ) + col1 ].append (
119- _get_left (tight_bbox , ax_bbox ))
120- # right
121- hspaces [row1 * (cols + 1 ) + (col1 + 1 )].append (
122- _get_right (tight_bbox , ax_bbox ))
123- # top
124- vspaces [row1 * cols + col1 ].append (
125- _get_top (tight_bbox , ax_bbox ))
126- # bottom
127- vspaces [(row1 + 1 ) * cols + col1 ].append (
128- _get_bottom (tight_bbox , ax_bbox ))
87+ num2 = num1
88+ row2 , col2 = divmod (num2 , cols )
12989
130- else :
131- row2 , col2 = divmod (num2 , cols )
132-
133- for row_i in range (row1 , row2 + 1 ):
134- # left
135- hspaces [row_i * (cols + 1 ) + col1 ].append (
136- _get_left (tight_bbox , ax_bbox ))
137- # right
138- hspaces [row_i * (cols + 1 ) + (col2 + 1 )].append (
139- _get_right (tight_bbox , ax_bbox ))
140- for col_i in range (col1 , col2 + 1 ):
141- # top
142- vspaces [row1 * cols + col_i ].append (
143- _get_top (tight_bbox , ax_bbox ))
144- # bottom
145- vspaces [(row2 + 1 ) * cols + col_i ].append (
146- _get_bottom (tight_bbox , ax_bbox ))
90+ for row_i in range (row1 , row2 + 1 ):
91+ hspaces [row_i , col1 ] += ax_bbox .xmin - tight_bbox .xmin # left
92+ hspaces [row_i , col2 + 1 ] += tight_bbox .xmax - ax_bbox .xmax # right
93+ for col_i in range (col1 , col2 + 1 ):
94+ vspaces [row1 , col_i ] += tight_bbox .ymax - ax_bbox .ymax # top
95+ vspaces [row2 + 1 , col_i ] += ax_bbox .ymin - tight_bbox .ymin # bot.
14796
14897 fig_width_inch , fig_height_inch = fig .get_size_inches ()
14998
150- # margins can be negative for axes with aspect applied. And we
151- # append + [0] to make minimum margins 0
152-
99+ # margins can be negative for axes with aspect applied, so use max(, 0) to
100+ # make them nonnegative.
153101 if not margin_left :
154- margin_left = max ([sum (s ) for s in hspaces [::cols + 1 ]] + [0 ])
155- margin_left += pad_inches / fig_width_inch
156-
102+ margin_left = (max (hspaces [:, 0 ].max (), 0 )
103+ + pad_inches / fig_width_inch )
157104 if not margin_right :
158- margin_right = max ([sum (s ) for s in hspaces [cols ::cols + 1 ]] + [0 ])
159- margin_right += pad_inches / fig_width_inch
160-
105+ margin_right = (max (hspaces [:, - 1 ].max (), 0 )
106+ + pad_inches / fig_width_inch )
161107 if not margin_top :
162- margin_top = max ([sum (s ) for s in vspaces [:cols ]] + [0 ])
163- margin_top += pad_inches / fig_height_inch
164-
108+ margin_top = (max (vspaces [0 , :].max (), 0 )
109+ + pad_inches / fig_height_inch )
165110 if not margin_bottom :
166- margin_bottom = max ([sum (s ) for s in vspaces [- cols :]] + [0 ])
167- margin_bottom += pad_inches / fig_height_inch
168-
111+ margin_bottom = (max (vspaces [- 1 , :].max (), 0 )
112+ + pad_inches / fig_height_inch )
169113 if margin_left + margin_right >= 1 :
170114 cbook ._warn_external ('Tight layout not applied. The left and right '
171115 'margins cannot be made large enough to '
@@ -181,12 +125,9 @@ def auto_adjust_subplotpars(
181125 right = 1 - margin_right ,
182126 bottom = margin_bottom ,
183127 top = 1 - margin_top )
128+
184129 if cols > 1 :
185- hspace = (
186- max (sum (s )
187- for i in range (rows )
188- for s in hspaces [i * (cols + 1 ) + 1 :(i + 1 ) * (cols + 1 ) - 1 ])
189- + hpad_inches / fig_width_inch )
130+ hspace = hspaces [:, 1 :- 1 ].max () + hpad_inches / fig_width_inch
190131 # axes widths:
191132 h_axes = (1 - margin_right - margin_left - hspace * (cols - 1 )) / cols
192133 if h_axes < 0 :
@@ -196,10 +137,8 @@ def auto_adjust_subplotpars(
196137 return None
197138 else :
198139 kwargs ["wspace" ] = hspace / h_axes
199-
200140 if rows > 1 :
201- vspace = (max (sum (s ) for s in vspaces [cols :- cols ])
202- + vpad_inches / fig_height_inch )
141+ vspace = vspaces [1 :- 1 , :].max () + vpad_inches / fig_height_inch
203142 v_axes = (1 - margin_top - margin_bottom - vspace * (rows - 1 )) / rows
204143 if v_axes < 0 :
205144 cbook ._warn_external ('Tight layout not applied. tight_layout '
0 commit comments