@@ -76,35 +76,15 @@ def get_axall_tightbbox(ax, renderer):
76
76
return bbox
77
77
78
78
79
- def in_same_column (ss0 , ssc ):
80
- nrows , ncols = ss0 .get_gridspec ().get_geometry ()
81
-
82
- if ss0 .num2 is None :
83
- ss0 .num2 = ss0 .num1
84
- rownum0min , colnum0min = divmod (ss0 .num1 , ncols )
85
- rownum0max , colnum0max = divmod (ss0 .num2 , ncols )
86
- if ssc .num2 is None :
87
- ssc .num2 = ssc .num1
88
- rownumCmin , colnumCmin = divmod (ssc .num1 , ncols )
89
- rownumCmax , colnumCmax = divmod (ssc .num2 , ncols )
79
+ def in_same_column (colnum0min , colnum0max , colnumCmin , colnumCmax ):
90
80
if colnum0min >= colnumCmin and colnum0min <= colnumCmax :
91
81
return True
92
82
if colnum0max >= colnumCmin and colnum0max <= colnumCmax :
93
83
return True
94
84
return False
95
85
96
86
97
- def in_same_row (ss0 , ssc ):
98
- nrows , ncols = ss0 .get_gridspec ().get_geometry ()
99
-
100
- if ss0 .num2 is None :
101
- ss0 .num2 = ss0 .num1
102
- rownum0min , colnum0min = divmod (ss0 .num1 , ncols )
103
- rownum0max , colnum0max = divmod (ss0 .num2 , ncols )
104
- if ssc .num2 is None :
105
- ssc .num2 = ssc .num1
106
- rownumCmin , colnumCmin = divmod (ssc .num1 , ncols )
107
- rownumCmax , colnumCmax = divmod (ssc .num2 , ncols )
87
+ def in_same_row (rownum0min , rownum0max , rownumCmin , rownumCmax ):
108
88
if rownum0min >= rownumCmin and rownum0min <= rownumCmax :
109
89
return True
110
90
if rownum0max >= rownumCmin and rownum0max <= rownumCmax :
@@ -177,6 +157,7 @@ def do_constrained_layout(fig, renderer, h_pad, w_pad,
177
157
margins) is very large. There must be a math way to check for this case.
178
158
179
159
'''
160
+
180
161
invTransFig = fig .transFigure .inverted ().transform_bbox
181
162
182
163
# list of unique gridspecs that contain child axes:
@@ -314,52 +295,77 @@ def do_constrained_layout(fig, renderer, h_pad, w_pad,
314
295
and ax ._layoutbox is not None ):
315
296
if ax .get_subplotspec ().get_gridspec () == gs :
316
297
axs += [ax ]
317
- for ax in axs :
318
- axs = axs [1 :]
298
+ rownummin = np .zeros (len (axs ), dtype = np .int8 )
299
+ rownummax = np .zeros (len (axs ), dtype = np .int8 )
300
+ colnummin = np .zeros (len (axs ), dtype = np .int8 )
301
+ colnummax = np .zeros (len (axs ), dtype = np .int8 )
302
+ width = np .zeros (len (axs ))
303
+ height = np .zeros (len (axs ))
304
+
305
+ for n , ax in enumerate (axs ):
306
+ ss0 = ax .get_subplotspec ()
307
+ if ss0 .num2 is None :
308
+ ss0 .num2 = ss0 .num1
309
+ rownummin [n ], colnummin [n ] = divmod (ss0 .num1 , ncols )
310
+ rownummax [n ], colnummax [n ] = divmod (ss0 .num2 , ncols )
311
+ width [n ] = np .sum (
312
+ width_ratios [colnummin [n ]:(colnummax [n ] + 1 )])
313
+ height [n ] = np .sum (
314
+ height_ratios [rownummin [n ]:(rownummax [n ] + 1 )])
315
+
316
+ for nn , ax in enumerate (axs [:- 1 ]):
317
+ ss0 = ax .get_subplotspec ()
318
+
319
319
# now compare ax to all the axs:
320
320
#
321
321
# If the subplotspecs have the same colnumXmax, then line
322
322
# up their right sides. If they have the same min, then
323
323
# line up their left sides (and vertical equivalents).
324
- ss0 = ax .get_subplotspec ()
325
- if ss0 .num2 is None :
326
- ss0 .num2 = ss0 .num1
327
- rownum0min , colnum0min = divmod (ss0 .num1 , ncols )
328
- rownum0max , colnum0max = divmod (ss0 .num2 , ncols )
329
- for axc in axs :
330
- ssc = axc .get_subplotspec ()
331
- # get the rownums and colnums
332
- rownumCmin , colnumCmin = divmod (ssc .num1 , ncols )
333
- if ssc .num2 is None :
334
- ssc .num2 = ssc .num1
335
- rownumCmax , colnumCmax = divmod (ssc .num2 , ncols )
336
-
324
+ rownum0min , colnum0min = rownummin [nn ], colnummin [nn ]
325
+ rownum0max , colnum0max = rownummax [nn ], colnummax [nn ]
326
+ width0 , height0 = width [nn ], height [nn ]
327
+ alignleft = False
328
+ alignright = False
329
+ alignbot = False
330
+ aligntop = False
331
+ alignheight = False
332
+ alignwidth = False
333
+ for mm in range (nn + 1 , len (axs )):
334
+ axc = axs [mm ]
335
+ rownumCmin , colnumCmin = rownummin [mm ], colnummin [mm ]
336
+ rownumCmax , colnumCmax = rownummax [mm ], colnummax [mm ]
337
+ widthC , heightC = width [mm ], height [mm ]
337
338
# Horizontally align axes spines if they have the
338
339
# same min or max:
339
- if colnum0min == colnumCmin :
340
+ if not alignleft and colnum0min == colnumCmin :
340
341
# we want the _poslayoutboxes to line up on left
341
342
# side of the axes spines...
342
343
layoutbox .align ([ax ._poslayoutbox ,
343
344
axc ._poslayoutbox ],
344
345
'left' )
345
- if colnum0max == colnumCmax :
346
+ alignleft = True
347
+
348
+ if not alignright and colnum0max == colnumCmax :
346
349
# line up right sides of _poslayoutbox
347
350
layoutbox .align ([ax ._poslayoutbox ,
348
351
axc ._poslayoutbox ],
349
352
'right' )
353
+ alignright = True
350
354
# Vertically align axes spines if they have the
351
355
# same min or max:
352
- if rownum0min == rownumCmin :
356
+ if not aligntop and rownum0min == rownumCmin :
353
357
# line up top of _poslayoutbox
354
358
_log .debug ('rownum0min == rownumCmin' )
355
359
layoutbox .align ([ax ._poslayoutbox , axc ._poslayoutbox ],
356
360
'top' )
357
- if rownum0max == rownumCmax :
361
+ aligntop = True
362
+
363
+ if not alignbot and rownum0max == rownumCmax :
358
364
# line up bottom of _poslayoutbox
359
365
_log .debug ('rownum0max == rownumCmax' )
360
366
layoutbox .align ([ax ._poslayoutbox , axc ._poslayoutbox ],
361
367
'bottom' )
362
-
368
+ alignbot = True
363
369
###########
364
370
# Now we make the widths and heights of position boxes
365
371
# similar. (i.e the spine locations)
@@ -377,57 +383,51 @@ def do_constrained_layout(fig, renderer, h_pad, w_pad,
377
383
# For height, this only needs to be done if the
378
384
# subplots share a column. For width if they
379
385
# share a row.
380
- widthC = np .sum (
381
- width_ratios [colnumCmin :(colnumCmax + 1 )])
382
- width0 = np .sum (
383
- width_ratios [colnum0min :(colnum0max + 1 )])
384
- heightC = np .sum (
385
- height_ratios [rownumCmin :(rownumCmax + 1 )])
386
- height0 = np .sum (
387
- height_ratios [rownum0min :(rownum0max + 1 )])
388
386
389
387
drowsC = (rownumCmax - rownumCmin + 1 )
390
388
drows0 = (rownum0max - rownum0min + 1 )
391
389
dcolsC = (colnumCmax - colnumCmin + 1 )
392
390
dcols0 = (colnum0max - colnum0min + 1 )
393
391
394
- if height0 > heightC :
395
- if in_same_column (ss0 , ssc ):
392
+ if not alignheight and drows0 == drowsC :
393
+ ax ._poslayoutbox .constrain_height (
394
+ axc ._poslayoutbox .height * height0 / heightC )
395
+ alignheight = True
396
+ elif in_same_column (colnum0min , colnum0max ,
397
+ colnumCmin , colnumCmax ):
398
+ if height0 > heightC :
396
399
ax ._poslayoutbox .constrain_height_min (
397
400
axc ._poslayoutbox .height * height0 / heightC )
398
401
# these constraints stop the smaller axes from
399
402
# being allowed to go to zero height...
400
403
axc ._poslayoutbox .constrain_height_min (
401
404
ax ._poslayoutbox .height * heightC /
402
405
(height0 * 1.8 ))
403
- else :
404
- if in_same_column (ss0 , ssc ):
406
+ elif height0 < heightC :
405
407
axc ._poslayoutbox .constrain_height_min (
406
408
ax ._poslayoutbox .height * heightC / height0 )
407
409
ax ._poslayoutbox .constrain_height_min (
408
410
ax ._poslayoutbox .height * height0 /
409
411
(heightC * 1.8 ))
410
- if drows0 == drowsC :
411
- ax ._poslayoutbox .constrain_height (
412
- axc ._poslayoutbox .height * height0 / heightC )
413
412
# widths...
414
- if width0 > widthC :
415
- if in_same_row (ss0 , ssc ):
413
+ if not alignwidth and dcols0 == dcolsC :
414
+ ax ._poslayoutbox .constrain_width (
415
+ axc ._poslayoutbox .width * width0 / widthC )
416
+ alignwidth = True
417
+ elif in_same_row (rownum0min , rownum0max ,
418
+ rownumCmin , rownumCmax ):
419
+ if width0 > widthC :
416
420
ax ._poslayoutbox .constrain_width_min (
417
421
axc ._poslayoutbox .width * width0 / widthC )
418
422
axc ._poslayoutbox .constrain_width_min (
419
423
ax ._poslayoutbox .width * widthC /
420
424
(width0 * 1.8 ))
421
- else :
422
- if in_same_row (ss0 , ssc ):
425
+ elif width0 < widthC :
423
426
axc ._poslayoutbox .constrain_width_min (
424
427
ax ._poslayoutbox .width * widthC / width0 )
425
428
ax ._poslayoutbox .constrain_width_min (
426
429
axc ._poslayoutbox .width * width0 /
427
430
(widthC * 1.8 ))
428
- if dcols0 == dcolsC :
429
- ax ._poslayoutbox .constrain_width (
430
- axc ._poslayoutbox .width * width0 / widthC )
431
431
432
432
fig ._layoutbox .constrained_layout_called += 1
433
433
fig ._layoutbox .update_variables ()
0 commit comments