@@ -76,35 +76,15 @@ def get_axall_tightbbox(ax, renderer):
7676 return bbox
7777
7878
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 ):
9080 if colnum0min >= colnumCmin and colnum0min <= colnumCmax :
9181 return True
9282 if colnum0max >= colnumCmin and colnum0max <= colnumCmax :
9383 return True
9484 return False
9585
9686
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 ):
10888 if rownum0min >= rownumCmin and rownum0min <= rownumCmax :
10989 return True
11090 if rownum0max >= rownumCmin and rownum0max <= rownumCmax :
@@ -177,6 +157,7 @@ def do_constrained_layout(fig, renderer, h_pad, w_pad,
177157 margins) is very large. There must be a math way to check for this case.
178158
179159 '''
160+
180161 invTransFig = fig .transFigure .inverted ().transform_bbox
181162
182163 # list of unique gridspecs that contain child axes:
@@ -314,52 +295,77 @@ def do_constrained_layout(fig, renderer, h_pad, w_pad,
314295 and ax ._layoutbox is not None ):
315296 if ax .get_subplotspec ().get_gridspec () == gs :
316297 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+
319319 # now compare ax to all the axs:
320320 #
321321 # If the subplotspecs have the same colnumXmax, then line
322322 # up their right sides. If they have the same min, then
323323 # 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 ]
337338 # Horizontally align axes spines if they have the
338339 # same min or max:
339- if colnum0min == colnumCmin :
340+ if not alignleft and colnum0min == colnumCmin :
340341 # we want the _poslayoutboxes to line up on left
341342 # side of the axes spines...
342343 layoutbox .align ([ax ._poslayoutbox ,
343344 axc ._poslayoutbox ],
344345 'left' )
345- if colnum0max == colnumCmax :
346+ alignleft = True
347+
348+ if not alignright and colnum0max == colnumCmax :
346349 # line up right sides of _poslayoutbox
347350 layoutbox .align ([ax ._poslayoutbox ,
348351 axc ._poslayoutbox ],
349352 'right' )
353+ alignright = True
350354 # Vertically align axes spines if they have the
351355 # same min or max:
352- if rownum0min == rownumCmin :
356+ if not aligntop and rownum0min == rownumCmin :
353357 # line up top of _poslayoutbox
354358 _log .debug ('rownum0min == rownumCmin' )
355359 layoutbox .align ([ax ._poslayoutbox , axc ._poslayoutbox ],
356360 'top' )
357- if rownum0max == rownumCmax :
361+ aligntop = True
362+
363+ if not alignbot and rownum0max == rownumCmax :
358364 # line up bottom of _poslayoutbox
359365 _log .debug ('rownum0max == rownumCmax' )
360366 layoutbox .align ([ax ._poslayoutbox , axc ._poslayoutbox ],
361367 'bottom' )
362-
368+ alignbot = True
363369 ###########
364370 # Now we make the widths and heights of position boxes
365371 # similar. (i.e the spine locations)
@@ -377,57 +383,51 @@ def do_constrained_layout(fig, renderer, h_pad, w_pad,
377383 # For height, this only needs to be done if the
378384 # subplots share a column. For width if they
379385 # 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 )])
388386
389387 drowsC = (rownumCmax - rownumCmin + 1 )
390388 drows0 = (rownum0max - rownum0min + 1 )
391389 dcolsC = (colnumCmax - colnumCmin + 1 )
392390 dcols0 = (colnum0max - colnum0min + 1 )
393391
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 :
396399 ax ._poslayoutbox .constrain_height_min (
397400 axc ._poslayoutbox .height * height0 / heightC )
398401 # these constraints stop the smaller axes from
399402 # being allowed to go to zero height...
400403 axc ._poslayoutbox .constrain_height_min (
401404 ax ._poslayoutbox .height * heightC /
402405 (height0 * 1.8 ))
403- else :
404- if in_same_column (ss0 , ssc ):
406+ elif height0 < heightC :
405407 axc ._poslayoutbox .constrain_height_min (
406408 ax ._poslayoutbox .height * heightC / height0 )
407409 ax ._poslayoutbox .constrain_height_min (
408410 ax ._poslayoutbox .height * height0 /
409411 (heightC * 1.8 ))
410- if drows0 == drowsC :
411- ax ._poslayoutbox .constrain_height (
412- axc ._poslayoutbox .height * height0 / heightC )
413412 # 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 :
416420 ax ._poslayoutbox .constrain_width_min (
417421 axc ._poslayoutbox .width * width0 / widthC )
418422 axc ._poslayoutbox .constrain_width_min (
419423 ax ._poslayoutbox .width * widthC /
420424 (width0 * 1.8 ))
421- else :
422- if in_same_row (ss0 , ssc ):
425+ elif width0 < widthC :
423426 axc ._poslayoutbox .constrain_width_min (
424427 ax ._poslayoutbox .width * widthC / width0 )
425428 ax ._poslayoutbox .constrain_width_min (
426429 axc ._poslayoutbox .width * width0 /
427430 (widthC * 1.8 ))
428- if dcols0 == dcolsC :
429- ax ._poslayoutbox .constrain_width (
430- axc ._poslayoutbox .width * width0 / widthC )
431431
432432 fig ._layoutbox .constrained_layout_called += 1
433433 fig ._layoutbox .update_variables ()
0 commit comments