9
9
for some cases (for example, left or right margin is affected by xlabel).
10
10
"""
11
11
12
+ import numpy as np
13
+
12
14
from matplotlib import cbook , rcParams
13
15
from matplotlib .font_manager import FontProperties
14
16
from matplotlib .transforms import TransformedBbox , Bbox
15
17
16
18
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
-
33
19
def auto_adjust_subplotpars (
34
20
fig , renderer , nrows_ncols , num1num2_list , subplot_list ,
35
21
ax_bbox_list = None , pad = 1.08 , h_pad = None , w_pad = None , rect = None ):
@@ -64,15 +50,8 @@ def auto_adjust_subplotpars(
64
50
font_size_inches = (
65
51
FontProperties (size = rcParams ["font.size" ]).get_size_in_points () / 72 )
66
52
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
76
55
77
56
if len (num1num2_list ) != len (subplot_list ) or len (subplot_list ) == 0 :
78
57
raise ValueError
@@ -81,23 +60,15 @@ def auto_adjust_subplotpars(
81
60
margin_left = margin_bottom = margin_right = margin_top = None
82
61
else :
83
62
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
95
65
96
- union = Bbox .union
66
+ vspaces = np .zeros ((rows + 1 , cols ))
67
+ hspaces = np .zeros ((rows , cols + 1 ))
97
68
98
69
if ax_bbox_list is None :
99
70
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 ])
101
72
for subplots in subplot_list ]
102
73
103
74
for subplots , ax_bbox , (num1 , num2 ) in zip (subplot_list ,
@@ -106,66 +77,39 @@ def auto_adjust_subplotpars(
106
77
if all (not ax .get_visible () for ax in subplots ):
107
78
continue
108
79
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 ()])
111
82
tight_bbox = TransformedBbox (tight_bbox_raw ,
112
83
fig .transFigure .inverted ())
113
84
114
85
row1 , col1 = divmod (num1 , cols )
115
-
116
86
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 )
129
89
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.
147
96
148
97
fig_width_inch , fig_height_inch = fig .get_size_inches ()
149
98
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.
153
101
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 )
157
104
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 )
161
107
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 )
165
110
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 )
169
113
if margin_left + margin_right >= 1 :
170
114
cbook ._warn_external ('Tight layout not applied. The left and right '
171
115
'margins cannot be made large enough to '
@@ -181,12 +125,9 @@ def auto_adjust_subplotpars(
181
125
right = 1 - margin_right ,
182
126
bottom = margin_bottom ,
183
127
top = 1 - margin_top )
128
+
184
129
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
190
131
# axes widths:
191
132
h_axes = (1 - margin_right - margin_left - hspace * (cols - 1 )) / cols
192
133
if h_axes < 0 :
@@ -196,10 +137,8 @@ def auto_adjust_subplotpars(
196
137
return None
197
138
else :
198
139
kwargs ["wspace" ] = hspace / h_axes
199
-
200
140
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
203
142
v_axes = (1 - margin_top - margin_bottom - vspace * (rows - 1 )) / rows
204
143
if v_axes < 0 :
205
144
cbook ._warn_external ('Tight layout not applied. tight_layout '
0 commit comments