@@ -254,13 +254,13 @@ def __init__(self, nrows=1, ncols=1, **kwargs):
254254 # Capture rc settings used for default spacing
255255 # NOTE: This is consistent with conversion of 'em' units to inches on gridspec
256256 # instantiation. In general it seems strange for future changes to rc settings
257- # to magically update an existing gridspec layout. This also may improve
258- # lookup time since get_grid_positions() is called heaviliy .
257+ # to magically update an existing gridspec layout. This also may improve draw
258+ # time as manual or auto figure resizes repeatedly call get_grid_positions() .
259259 scales = {'in' : 0 , 'inout' : 0.5 , 'out' : 1 , None : 1 }
260260 self ._xtickspace = scales [rc ['xtick.direction' ]] * rc ['xtick.major.size' ]
261261 self ._ytickspace = scales [rc ['ytick.direction' ]] * rc ['ytick.major.size' ]
262262 self ._xticklabelspace = _fontsize_to_pt (rc ['xtick.labelsize' ]) + rc ['xtick.major.pad' ] # noqa: E501
263- self ._yticklabelspace = 3 * _fontsize_to_pt (rc ['ytick.labelsize' ]) + rc ['ytick.major.pad' ] # noqa: E501
263+ self ._yticklabelspace = 2 * _fontsize_to_pt (rc ['ytick.labelsize' ]) + rc ['ytick.major.pad' ] # noqa: E501
264264 self ._labelspace = _fontsize_to_pt (rc ['axes.labelsize' ]) + rc ['axes.labelpad' ]
265265 self ._titlespace = _fontsize_to_pt (rc ['axes.titlesize' ]) + rc ['axes.titlepad' ]
266266
@@ -507,9 +507,6 @@ def _insert_panel_slot(
507507 and the `arg` is either an axes instance or the figure row-column span.
508508 """
509509 # Parse input args and get user-input properties, default properties
510- # NOTE: This gives totally wrong space for 'right' and 'top' colorbars with
511- # tick locations on the outside but that's ok... otherwise would have to
512- # modify existing space which is overkill. People should use tight layout
513510 fig = self .figure
514511 if fig is None :
515512 raise RuntimeError ('Figure must be assigned to gridspec.' )
@@ -519,63 +516,84 @@ def _insert_panel_slot(
519516 pad = units (pad , 'em' , 'in' )
520517 space = units (space , 'em' , 'in' )
521518 width = units (width , 'in' )
522- share = False if filled else _not_none ( share , True )
519+ share = False if filled else share if share is not None else True
523520 which = 'w' if side in ('left' , 'right' ) else 'h'
524521 panels = getattr (self , f'_{ which } panels' )
525522 pads = getattr (self , f'_{ which } pad_total' ) # no copies!
526523 ratios = getattr (self , f'_{ which } ratios_total' )
527524 spaces = getattr (self , f'_{ which } space_total' )
528525 spaces_default = getattr (self , f'_{ which } space_total_default' )
526+ new_outer_slot = idx in (- 1 , len (panels ))
527+ new_inner_slot = not new_outer_slot and panels [idx ] != slot
528+
529+ # Retrieve default spaces
530+ # NOTE: Cannot use 'wspace' and 'hspace' for top and right colorbars because
531+ # that adds an unnecessary tick space. So bypass _get_default_space totally.
529532 pad_default = (
530533 self ._panelpad
531534 if slot != 'f'
532535 or side in ('left' , 'top' ) and panels [0 ] == 'f'
533536 or side in ('right' , 'bottom' ) and panels [- 1 ] == 'f'
534537 else self ._innerpad
535538 )
536- space_default = (
539+ inner_space_default = (
537540 _not_none (pad , pad_default )
538541 if side in ('top' , 'right' )
539542 else self ._get_default_space (
540543 'hspace_total' if side == 'bottom' else 'wspace_total' ,
541- title = False , # no title space
542- share = 3 if share else 0 ,
544+ title = False , # no title between subplot and panel
545+ share = 3 if share else 0 , # space for main subplot labels
543546 pad = _not_none (pad , pad_default ),
544547 )
545548 )
549+ outer_space_default = self ._get_default_space (
550+ 'bottom' if not share and side == 'top'
551+ else 'left' if not share and side == 'right'
552+ else side ,
553+ title = True , # room for titles deflected above panels
554+ pad = self ._outerpad if new_outer_slot else self ._innerpad ,
555+ )
556+ if new_inner_slot :
557+ outer_space_default += self ._get_default_space (
558+ 'hspace_total' if side in ('bottom' , 'top' ) else 'wspace_total' ,
559+ share = None , # use external share setting
560+ pad = 0 , # use no additional padding
561+ )
546562 width_default = units (
547563 rc ['colorbar.width' if filled else 'subplots.panelwidth' ], 'in'
548564 )
549565
550566 # Adjust space, ratio, and panel indicator arrays
551567 # If slot exists, overwrite width, pad, space if they were provided by the user
552568 # If slot does not exist, modify gemoetry and add insert new spaces
553- newrow = newcol = None
554- idx_off = 1 * bool (side in ('top' , 'left' ))
555- idx_space = idx - 1 * bool (side in ('bottom' , 'right' ))
556- slot_exists = idx not in (- 1 , len (panels )) and panels [idx ] == slot
557- if slot_exists :
558- spaces_default [idx_space ] = space_default
569+ attr = 'ncols' if side in ('left' , 'right' ) else 'nrows'
570+ idx_offset = int (side in ('top' , 'left' ))
571+ idx_inner_space = idx - int (side in ('bottom' , 'right' )) # inner colorbar space
572+ idx_outer_space = idx - int (side in ('top' , 'left' )) # outer colorbar space
573+ if new_outer_slot or new_inner_slot :
574+ idx += idx_offset
575+ idx_inner_space += idx_offset
576+ idx_outer_space += idx_offset
577+ newcol , newrow = (idx , None ) if attr == 'ncols' else (None , idx )
578+ setattr (self , f'_{ attr } _total' , 1 + getattr (self , f'_{ attr } _total' ))
579+ panels .insert (idx , slot )
580+ ratios .insert (idx , _not_none (width , width_default ))
581+ pads .insert (idx_inner_space , _not_none (pad , pad_default ))
582+ spaces .insert (idx_inner_space , space )
583+ spaces_default .insert (idx_inner_space , inner_space_default )
584+ if new_inner_slot :
585+ spaces_default .insert (idx_outer_space , outer_space_default )
586+ else :
587+ setattr (self , f'_{ side } _default' , outer_space_default )
588+ else :
589+ newrow = newcol = None
590+ spaces_default [idx_inner_space ] = inner_space_default
559591 if width is not None :
560592 ratios [idx ] = width
561593 if pad is not None :
562- pads [idx_space ] = pad
594+ pads [idx_inner_space ] = pad
563595 if space is not None :
564- spaces [idx_space ] = space
565- else :
566- idx += idx_off
567- idx_space += idx_off
568- if side in ('left' , 'right' ):
569- newcol = idx
570- self ._ncols_total += 1
571- else :
572- newrow = idx
573- self ._nrows_total += 1
574- panels .insert (idx , slot )
575- ratios .insert (idx , _not_none (width , width_default ))
576- pads .insert (idx_space , _not_none (pad , pad_default ))
577- spaces .insert (idx_space , space )
578- spaces_default .insert (idx_space , space_default )
596+ spaces [idx_inner_space ] = space
579597
580598 # Update the figure and axes and return a SubplotSpec
581599 # NOTE: For figure panels indices are determined by user-input spans.
@@ -591,8 +609,8 @@ def _insert_panel_slot(
591609
592610 def _get_space (self , key ):
593611 """
594- Get the currently active space accounting for both default
595- values and explicit user-specified values .
612+ Return the currently active vector inner space or scalar outer space
613+ accounting for both default values and explicit user overrides .
596614 """
597615 # NOTE: Default panel spaces should have been filled by _insert_panel_slot.
598616 # They use 'panelpad' and the panel-local 'share' setting. This function
@@ -622,8 +640,8 @@ def _get_space(self, key):
622640
623641 def _get_default_space (self , key , pad = None , share = None , title = True ):
624642 """
625- Return suitable default spacing given a shared axes setting.
626- This is only relevant when "tight layout" is disabled.
643+ Return suitable default scalar inner or outer space given a shared axes
644+ setting. This is only relevant when "tight layout" is disabled.
627645 """
628646 # NOTE: Internal spacing args are stored in inches to simplify the
629647 # get_grid_positions() calculations.
@@ -642,15 +660,15 @@ def _get_default_space(self, key, pad=None, share=None, title=True):
642660 elif key == 'bottom' :
643661 pad = _not_none (pad , self ._outerpad )
644662 space = self ._labelspace + self ._xticklabelspace + self ._xtickspace
645- elif key in ( 'wspace' , ' wspace_total') :
663+ elif key == ' wspace_total' :
646664 pad = _not_none (pad , self ._innerpad )
647665 share = _not_none (share , fig ._sharey , 0 )
648666 space = self ._ytickspace
649667 if share < 3 :
650668 space += self ._yticklabelspace
651669 if share < 1 :
652670 space += self ._labelspace
653- elif key in ( 'hspace' , ' hspace_total') :
671+ elif key == ' hspace_total' :
654672 pad = _not_none (pad , self ._innerpad )
655673 share = _not_none (share , fig ._sharex , 0 )
656674 space = self ._xtickspace
0 commit comments