def _arrange_subplotspecs(gs, hspace=0, wspace=0): """Recursively arrange the subplotspec children of the given gridspec.""" sschildren = [] for child in gs.children: if child._is_subplotspec_layoutbox(): for child2 in child.children: # check for gridspec children... if child2._is_gridspec_layoutbox(): _arrange_subplotspecs(child2, hspace=hspace, wspace=wspace) sschildren += [child] # now arrange the subplots... for child0 in sschildren: ss0 = child0.artist nrows, ncols = ss0.get_gridspec().get_geometry() rowspan0 = ss0.rowspan colspan0 = ss0.colspan sschildren = sschildren[1:] for child1 in sschildren: ss1 = child1.artist rowspan1 = ss1.rowspan colspan1 = ss1.colspan # OK, this tells us the relative layout of child0 with child1. pad = wspace / ncols if colspan0.stop <= colspan1.start: layoutbox.hstack([ss0._layoutbox, ss1._layoutbox], padding=pad) if colspan1.stop <= colspan0.start: layoutbox.hstack([ss1._layoutbox, ss0._layoutbox], padding=pad) # vertical alignment pad = hspace / nrows if rowspan0.stop <= rowspan1.start: layoutbox.vstack([ss0._layoutbox, ss1._layoutbox], padding=pad) if rowspan1.stop <= rowspan0.start: layoutbox.vstack([ss1._layoutbox, ss0._layoutbox], padding=pad)
def layoutcolorbarsingle(ax, cax, shrink, aspect, location, pad=0.05): """ Do the layout for a colorbar, to not oeverly pollute colorbar.py `pad` is in fraction of the original axis size. """ axlb = ax._layoutbox axpos = ax._poslayoutbox axsslb = ax.get_subplotspec()._layoutbox lb = layoutbox.LayoutBox( parent=axsslb, name=axsslb.name + '.cbar', artist=cax) if location in ('left', 'right'): lbpos = layoutbox.LayoutBox( parent=lb, name=lb.name + '.pos', tightwidth=False, pos=True, subplot=False, artist=cax) if location == 'right': # arrange to right of parent axis layoutbox.hstack([axlb, lb], padding=pad * axlb.width, strength='strong') else: layoutbox.hstack([lb, axlb], padding=pad * axlb.width) # constrain the height and center... layoutbox.match_heights([axpos, lbpos], [1, shrink]) layoutbox.align([axpos, lbpos], 'v_center') # set the width of the pos box lbpos.constrain_width(shrink * axpos.height * (1/aspect), strength='strong') elif location in ('bottom', 'top'): lbpos = layoutbox.LayoutBox( parent=lb, name=lb.name + '.pos', tightheight=True, pos=True, subplot=False, artist=cax) if location == 'bottom': layoutbox.vstack([axlb, lb], padding=pad * axlb.height) else: layoutbox.vstack([lb, axlb], padding=pad * axlb.height) # constrain the height and center... layoutbox.match_widths([axpos, lbpos], [1, shrink], strength='strong') layoutbox.align([axpos, lbpos], 'h_center') # set the height of the pos box lbpos.constrain_height(axpos.width * aspect * shrink, strength='medium') return lb, lbpos
def layoutcolorbarsingle(ax, cax, shrink, aspect, location, pad=0.05): """ Do the layout for a colorbar, to not overly pollute colorbar.py *pad* is in fraction of the original axis size. """ axlb = ax._layoutbox axpos = ax._poslayoutbox axsslb = ax.get_subplotspec()._layoutbox lb = layoutbox.LayoutBox( parent=axsslb, name=axsslb.name + '.cbar', artist=cax) if location in ('left', 'right'): lbpos = layoutbox.LayoutBox( parent=lb, name=lb.name + '.pos', tightwidth=False, pos=True, subplot=False, artist=cax) if location == 'right': # arrange to right of parent axis layoutbox.hstack([axlb, lb], padding=pad * axlb.width, strength='strong') else: layoutbox.hstack([lb, axlb], padding=pad * axlb.width) # constrain the height and center... layoutbox.match_heights([axpos, lbpos], [1, shrink]) layoutbox.align([axpos, lbpos], 'v_center') # set the width of the pos box lbpos.constrain_width(shrink * axpos.height * (1/aspect), strength='strong') elif location in ('bottom', 'top'): lbpos = layoutbox.LayoutBox( parent=lb, name=lb.name + '.pos', tightheight=True, pos=True, subplot=False, artist=cax) if location == 'bottom': layoutbox.vstack([axlb, lb], padding=pad * axlb.height) else: layoutbox.vstack([lb, axlb], padding=pad * axlb.height) # constrain the height and center... layoutbox.match_widths([axpos, lbpos], [1, shrink], strength='strong') layoutbox.align([axpos, lbpos], 'h_center') # set the height of the pos box lbpos.constrain_height(axpos.width * aspect * shrink, strength='medium') return lb, lbpos
def arange_subplotspecs(gs, hspace=0, wspace=0): """ arange the subplotspec children of this gridspec, and then recursively do the same of any gridspec children of those gridspecs... """ sschildren = [] for child in gs.children: if child._is_subplotspec_layoutbox(): for child2 in child.children: # check for gridspec children... name = (child2.name).split('.')[-1][:-3] if name == 'gridspec': arange_subplotspecs(child2, hspace=hspace, wspace=wspace) sschildren += [child] # now arrange the subplots... for child0 in sschildren: ss0 = child0.artist nrows, ncols = ss0.get_gridspec().get_geometry() if ss0.num2 is None: ss0.num2 = ss0.num1 rowNum0min, colNum0min = divmod(ss0.num1, ncols) rowNum0max, colNum0max = divmod(ss0.num2, ncols) sschildren = sschildren[1:] for childc in sschildren: ssc = childc.artist rowNumCmin, colNumCmin = divmod(ssc.num1, ncols) if ssc.num2 is None: ssc.num2 = ssc.num1 rowNumCmax, colNumCmax = divmod(ssc.num2, ncols) # OK, this tells us the relative layout of ax # with axc thepad = wspace / ncols if colNum0max < colNumCmin: layoutbox.hstack([ss0._layoutbox, ssc._layoutbox], padding=thepad) if colNumCmax < colNum0min: layoutbox.hstack([ssc._layoutbox, ss0._layoutbox], padding=thepad) #### # vertical alignment thepad = hspace / nrows if rowNum0max < rowNumCmin: layoutbox.vstack([ss0._layoutbox, ssc._layoutbox], padding=thepad) if rowNumCmax < rowNum0min: layoutbox.vstack([ssc._layoutbox, ss0._layoutbox], padding=thepad)
def _arrange_subplotspecs(gs, hspace=0, wspace=0): """Recursively arrange the subplotspec children of the given gridspec.""" sschildren = [] for child in gs.children: if child._is_subplotspec_layoutbox(): for child2 in child.children: # check for gridspec children... if child2._is_gridspec_layoutbox(): _arrange_subplotspecs(child2, hspace=hspace, wspace=wspace) sschildren += [child] # now arrange the subplots... for child0 in sschildren: ss0 = child0.artist nrows, ncols = ss0.get_gridspec().get_geometry() rowNum0min, colNum0min = divmod(ss0.num1, ncols) rowNum0max, colNum0max = divmod(ss0.num2, ncols) sschildren = sschildren[1:] for childc in sschildren: ssc = childc.artist rowNumCmin, colNumCmin = divmod(ssc.num1, ncols) rowNumCmax, colNumCmax = divmod(ssc.num2, ncols) # OK, this tells us the relative layout of ax # with axc thepad = wspace / ncols if colNum0max < colNumCmin: layoutbox.hstack([ss0._layoutbox, ssc._layoutbox], padding=thepad) if colNumCmax < colNum0min: layoutbox.hstack([ssc._layoutbox, ss0._layoutbox], padding=thepad) #### # vertical alignment thepad = hspace / nrows if rowNum0max < rowNumCmin: layoutbox.vstack([ss0._layoutbox, ssc._layoutbox], padding=thepad) if rowNumCmax < rowNum0min: layoutbox.vstack([ssc._layoutbox, ss0._layoutbox], padding=thepad)
def constrain_text(fig, text): """ Hack to constrain text on the bottom of the figure from matplotlib.figure.Figure.suptitle """ # pylint: disable=unused-variable,protected-access if fig._layoutbox is not None: w_pad, h_pad, wspace, hspace = fig.get_constrained_layout_pads( relative=True ) figlb = fig._layoutbox text._layoutbox = layoutbox.LayoutBox( parent=figlb, artist=text, name=figlb.name+'.textinfo' ) # stack the text on bottom of all the children. for child in figlb.children: if child is not text._layoutbox: layoutbox.vstack( [child, text._layoutbox], padding=h_pad*2., strength='required' )
def layoutcolorbargridspec(parents, cax, shrink, aspect, location, pad=0.05): """ Do the layout for a colorbar, to not oeverly pollute colorbar.py `pad` is in fraction of the original axis size. """ gs = parents[0].get_subplotspec().get_gridspec() # parent layout box.... gslb = gs._layoutbox lb = layoutbox.LayoutBox(parent=gslb.parent, name=gslb.parent.name + '.cbar', artist=cax) # figure out the row and column extent of the parents. (minrow, maxrow, minax_row, maxax_row, mincol, maxcol, minax_col, maxax_col) = _getmaxminrowcolumn(parents) if location in ('left', 'right'): lbpos = layoutbox.LayoutBox( parent=lb, name=lb.name + '.pos', tightwidth=False, pos=True, subplot=False, artist=cax) for ax in parents: if location == 'right': order = [ax._layoutbox, lb] else: order = [lb, ax._layoutbox] layoutbox.hstack(order, padding=pad * gslb.width, strength='strong') # constrain the height and center... # This isn't quite right. We'd like the colorbar # pos to line up w/ the axes poss, not the size of the # gs. # Horizontal Layout: need to check all the axes in this gridspec for ch in gslb.children: subspec = ch.artist nrows, ncols, row_start, row_stop, col_start, col_stop = \ subspec.get_rows_columns() if location == 'right': if col_stop <= maxcol: order = [subspec._layoutbox, lb] # arrange to right of the parents if col_start > maxcol: order = [lb, subspec._layoutbox] elif location == 'left': if col_start >= mincol: order = [lb, subspec._layoutbox] if col_stop < mincol: order = [subspec._layoutbox, lb] layoutbox.hstack(order, padding=pad * gslb.width, strength='strong') # Vertical layout: maxposlb = minax_row._poslayoutbox minposlb = maxax_row._poslayoutbox # now we want the height of the colorbar pos to be # set by the top and bottom of the min/max axes... # bottom top # b t # h = (top-bottom)*shrink # b = bottom + (top-bottom - h) / 2. lbpos.constrain_height( (maxposlb.top - minposlb.bottom) * shrink, strength='strong') lbpos.constrain_bottom( (maxposlb.top - minposlb.bottom) * (1 - shrink)/2 + minposlb.bottom, strength='strong') # set the width of the pos box lbpos.constrain_width(lbpos.height * (shrink / aspect), strength='strong') elif location in ('bottom', 'top'): lbpos = layoutbox.LayoutBox( parent=lb, name=lb.name + '.pos', tightheight=True, pos=True, subplot=False, artist=cax) for ax in parents: if location == 'bottom': order = [ax._layoutbox, lb] else: order = [lb, ax._layoutbox] layoutbox.vstack(order, padding=pad * gslb.width, strength='strong') # Vertical Layout: need to check all the axes in this gridspec for ch in gslb.children: subspec = ch.artist nrows, ncols, row_start, row_stop, col_start, col_stop = \ subspec.get_rows_columns() if location == 'bottom': if row_stop <= minrow: order = [subspec._layoutbox, lb] if row_start > maxrow: order = [lb, subspec._layoutbox] elif location == 'top': if row_stop < minrow: order = [subspec._layoutbox, lb] if row_start >= maxrow: order = [lb, subspec._layoutbox] layoutbox.vstack(order, padding=pad * gslb.width, strength='strong') # Do horizontal layout... maxposlb = maxax_col._poslayoutbox minposlb = minax_col._poslayoutbox lbpos.constrain_width((maxposlb.right - minposlb.left) * shrink) lbpos.constrain_left( (maxposlb.right - minposlb.left) * (1-shrink)/2 + minposlb.left) # set the height of the pos box lbpos.constrain_height(lbpos.width * shrink * aspect, strength='medium') return lb, lbpos
def layoutcolorbargridspec(parents, cax, shrink, aspect, location, pad=0.05): """ Do the layout for a colorbar, to not oeverly pollute colorbar.py `pad` is in fraction of the original axis size. """ gs = parents[0].get_subplotspec().get_gridspec() # parent layout box.... gslb = gs._layoutbox lb = layoutbox.LayoutBox(parent=gslb.parent, name=gslb.parent.name + '.cbar', artist=cax) if location in ('left', 'right'): lbpos = layoutbox.LayoutBox( parent=lb, name=lb.name + '.pos', tightwidth=False, pos=True, subplot=False, artist=cax) if location == 'right': # arrange to right of the gridpec sibbling layoutbox.hstack([gslb, lb], padding=pad * gslb.width, strength='strong') else: layoutbox.hstack([lb, gslb], padding=pad * gslb.width) # constrain the height and center... # This isn't quite right. We'd like the colorbar # pos to line up w/ the axes poss, not the size of the # gs. maxrow = -100000 minrow = 1000000 maxax = None minax = None for ax in parents: subspec = ax.get_subplotspec() nrows, ncols = subspec.get_gridspec().get_geometry() for num in [subspec.num1, subspec.num2]: rownum1, colnum1 = divmod(subspec.num1, ncols) if rownum1 > maxrow: maxrow = rownum1 maxax = ax if rownum1 < minrow: minrow = rownum1 minax = ax # invert the order so these are bottom to top: maxposlb = minax._poslayoutbox minposlb = maxax._poslayoutbox # now we want the height of the colorbar pos to be # set by the top and bottom of these poss # bottom top # b t # h = (top-bottom)*shrink # b = bottom + (top-bottom - h) / 2. lbpos.constrain_height( (maxposlb.top - minposlb.bottom) * shrink, strength='strong') lbpos.constrain_bottom( (maxposlb.top - minposlb.bottom) * (1 - shrink)/2 + minposlb.bottom, strength='strong') # set the width of the pos box lbpos.constrain_width(lbpos.height * (shrink / aspect), strength='strong') elif location in ('bottom', 'top'): lbpos = layoutbox.LayoutBox( parent=lb, name=lb.name + '.pos', tightheight=True, pos=True, subplot=False, artist=cax) if location == 'bottom': layoutbox.vstack([gslb, lb], padding=pad * gslb.width) else: layoutbox.vstack([lb, gslb], padding=pad * gslb.width) maxcol = -100000 mincol = 1000000 maxax = None minax = None for ax in parents: subspec = ax.get_subplotspec() nrows, ncols = subspec.get_gridspec().get_geometry() for num in [subspec.num1, subspec.num2]: rownum1, colnum1 = divmod(subspec.num1, ncols) if colnum1 > maxcol: maxcol = colnum1 maxax = ax if rownum1 < mincol: mincol = colnum1 minax = ax maxposlb = maxax._poslayoutbox minposlb = minax._poslayoutbox lbpos.constrain_width((maxposlb.right - minposlb.left) * shrink) lbpos.constrain_left( (maxposlb.right - minposlb.left) * (1-shrink)/2 + minposlb.left) # set the height of the pos box lbpos.constrain_height(lbpos.width * shrink * aspect, strength='medium') return lb, lbpos
def layoutcolorbargridspec(parents, cax, shrink, aspect, location, pad=0.05): """ Do the layout for a colorbar, to not oeverly pollute colorbar.py `pad` is in fraction of the original axis size. """ gs = parents[0].get_subplotspec().get_gridspec() # parent layout box.... gslb = gs._layoutbox lb = layoutbox.LayoutBox(parent=gslb.parent, name=gslb.parent.name + '.cbar', artist=cax) if location in ('left', 'right'): lbpos = layoutbox.LayoutBox(parent=lb, name=lb.name + '.pos', tightwidth=False, pos=True, subplot=False, artist=cax) if location == 'right': # arrange to right of the gridpec sibbling layoutbox.hstack([gslb, lb], padding=pad * gslb.width, strength='strong') else: layoutbox.hstack([lb, gslb], padding=pad * gslb.width) # constrain the height and center... # This isn't quite right. We'd like the colorbar # pos to line up w/ the axes poss, not the size of the # gs. maxrow = -100000 minrow = 1000000 maxax = None minax = None for ax in parents: subspec = ax.get_subplotspec() nrows, ncols = subspec.get_gridspec().get_geometry() for num in [subspec.num1, subspec.num2]: rownum1, colnum1 = divmod(subspec.num1, ncols) if rownum1 > maxrow: maxrow = rownum1 maxax = ax if rownum1 < minrow: minrow = rownum1 minax = ax # invert the order so these are bottom to top: maxposlb = minax._poslayoutbox minposlb = maxax._poslayoutbox # now we want the height of the colorbar pos to be # set by the top and bottom of these poss # bottom top # b t # h = (top-bottom)*shrink # b = bottom + (top-bottom - h) / 2. lbpos.constrain_height((maxposlb.top - minposlb.bottom) * shrink, strength='strong') lbpos.constrain_bottom((maxposlb.top - minposlb.bottom) * (1 - shrink) / 2 + minposlb.bottom, strength='strong') # set the width of the pos box lbpos.constrain_width(lbpos.height * (shrink / aspect), strength='strong') elif location in ('bottom', 'top'): lbpos = layoutbox.LayoutBox(parent=lb, name=lb.name + '.pos', tightheight=True, pos=True, subplot=False, artist=cax) if location == 'bottom': layoutbox.vstack([gslb, lb], padding=pad * gslb.width) else: layoutbox.vstack([lb, gslb], padding=pad * gslb.width) maxcol = -100000 mincol = 1000000 maxax = None minax = None for ax in parents: subspec = ax.get_subplotspec() nrows, ncols = subspec.get_gridspec().get_geometry() for num in [subspec.num1, subspec.num2]: rownum1, colnum1 = divmod(subspec.num1, ncols) if colnum1 > maxcol: maxcol = colnum1 maxax = ax if rownum1 < mincol: mincol = colnum1 minax = ax maxposlb = maxax._poslayoutbox minposlb = minax._poslayoutbox lbpos.constrain_width((maxposlb.right - minposlb.left) * shrink) lbpos.constrain_left((maxposlb.right - minposlb.left) * (1 - shrink) / 2 + minposlb.left) # set the height of the pos box lbpos.constrain_height(lbpos.width * shrink * aspect, strength='medium') return lb, lbpos
def layoutcolorbargridspec(parents, cax, shrink, aspect, location, pad=0.05): """ Do the layout for a colorbar, to not overly pollute colorbar.py `pad` is in fraction of the original axis size. """ gs = parents[0].get_subplotspec().get_gridspec() # parent layout box.... gslb = gs._layoutbox lb = layoutbox.LayoutBox(parent=gslb.parent, name=gslb.parent.name + '.cbar', artist=cax) # figure out the row and column extent of the parents. (minrow, maxrow, minax_row, maxax_row, mincol, maxcol, minax_col, maxax_col) = _getmaxminrowcolumn(parents) if location in ('left', 'right'): lbpos = layoutbox.LayoutBox(parent=lb, name=lb.name + '.pos', tightwidth=False, pos=True, subplot=False, artist=cax) for ax in parents: if location == 'right': order = [ax._layoutbox, lb] else: order = [lb, ax._layoutbox] layoutbox.hstack(order, padding=pad * gslb.width, strength='strong') # constrain the height and center... # This isn't quite right. We'd like the colorbar # pos to line up w/ the axes poss, not the size of the # gs. # Horizontal Layout: need to check all the axes in this gridspec for ch in gslb.children: subspec = ch.artist nrows, ncols, row_start, row_stop, col_start, col_stop = \ subspec.get_rows_columns() if location == 'right': if col_stop <= maxcol: order = [subspec._layoutbox, lb] # arrange to right of the parents if col_start > maxcol: order = [lb, subspec._layoutbox] elif location == 'left': if col_start >= mincol: order = [lb, subspec._layoutbox] if col_stop < mincol: order = [subspec._layoutbox, lb] layoutbox.hstack(order, padding=pad * gslb.width, strength='strong') # Vertical layout: maxposlb = minax_row._poslayoutbox minposlb = maxax_row._poslayoutbox # now we want the height of the colorbar pos to be # set by the top and bottom of the min/max axes... # bottom top # b t # h = (top-bottom)*shrink # b = bottom + (top-bottom - h) / 2. lbpos.constrain_height((maxposlb.top - minposlb.bottom) * shrink, strength='strong') lbpos.constrain_bottom((maxposlb.top - minposlb.bottom) * (1 - shrink) / 2 + minposlb.bottom, strength='strong') # set the width of the pos box lbpos.constrain_width(lbpos.height * (shrink / aspect), strength='strong') elif location in ('bottom', 'top'): lbpos = layoutbox.LayoutBox(parent=lb, name=lb.name + '.pos', tightheight=True, pos=True, subplot=False, artist=cax) for ax in parents: if location == 'bottom': order = [ax._layoutbox, lb] else: order = [lb, ax._layoutbox] layoutbox.vstack(order, padding=pad * gslb.width, strength='strong') # Vertical Layout: need to check all the axes in this gridspec for ch in gslb.children: subspec = ch.artist nrows, ncols, row_start, row_stop, col_start, col_stop = \ subspec.get_rows_columns() if location == 'bottom': if row_stop <= minrow: order = [subspec._layoutbox, lb] if row_start > maxrow: order = [lb, subspec._layoutbox] elif location == 'top': if row_stop < minrow: order = [subspec._layoutbox, lb] if row_start >= maxrow: order = [lb, subspec._layoutbox] layoutbox.vstack(order, padding=pad * gslb.width, strength='strong') # Do horizontal layout... maxposlb = maxax_col._poslayoutbox minposlb = minax_col._poslayoutbox lbpos.constrain_width((maxposlb.right - minposlb.left) * shrink) lbpos.constrain_left((maxposlb.right - minposlb.left) * (1 - shrink) / 2 + minposlb.left) # set the height of the pos box lbpos.constrain_height(lbpos.width * shrink * aspect, strength='medium') return lb, lbpos