Axes class - set explicitly size (width/height) of axes in given units Axes class - set explicitly size (width/height) of axes in given units python python

Axes class - set explicitly size (width/height) of axes in given units


The axes size is determined by the figure size and the figure spacings, which can be set using figure.subplots_adjust(). In reverse this means that you can set the axes size by setting the figure size taking into acount the figure spacings:

import matplotlib.pyplot as pltdef set_size(w,h, ax=None):    """ w, h: width, height in inches """    if not ax: ax=plt.gca()    l = ax.figure.subplotpars.left    r = ax.figure.subplotpars.right    t = ax.figure.subplotpars.top    b = ax.figure.subplotpars.bottom    figw = float(w)/(r-l)    figh = float(h)/(t-b)    ax.figure.set_size_inches(figw, figh)fig, ax=plt.subplots()ax.plot([1,3,2])set_size(5,5)plt.show()


It appears that Matplotlib has helper classes that allow you to define axes with a fixed size Demo fixed size axes


I have found that ImportanceofBeingErnests answer which modifies that figure size to adjust the axes size provides inconsistent results with the paticular matplotlib settings I use to produce publication ready plots. Slight errors were present in the final figure size, and I was unable to find a way to solve the issue with his approach. For most use cases I think this is not a problem, however the errors were noticeable when combining multiple pdf's for publication.

In lieu of developing a minimum working example to find the real issue I am having with the figure resizing approach I instead found a work around which uses the fixed axes size utilising the divider class.

from mpl_toolkits.axes_grid1 import Divider, Sizedef fix_axes_size_incm(axew, axeh):    axew = axew/2.54    axeh = axeh/2.54    #lets use the tight layout function to get a good padding size for our axes labels.    fig = plt.gcf()    ax = plt.gca()    fig.tight_layout()    #obtain the current ratio values for padding and fix size    oldw, oldh = fig.get_size_inches()    l = ax.figure.subplotpars.left    r = ax.figure.subplotpars.right    t = ax.figure.subplotpars.top    b = ax.figure.subplotpars.bottom    #work out what the new  ratio values for padding are, and the new fig size.    neww = axew+oldw*(1-r+l)    newh = axeh+oldh*(1-t+b)    newr = r*oldw/neww    newl = l*oldw/neww    newt = t*oldh/newh    newb = b*oldh/newh    #right(top) padding, fixed axes size, left(bottom) pading    hori = [Size.Scaled(newr), Size.Fixed(axew), Size.Scaled(newl)]    vert = [Size.Scaled(newt), Size.Fixed(axeh), Size.Scaled(newb)]    divider = Divider(fig, (0.0, 0.0, 1., 1.), hori, vert, aspect=False)    # the width and height of the rectangle is ignored.    ax.set_axes_locator(divider.new_locator(nx=1, ny=1))    #we need to resize the figure now, as we have may have made our axes bigger than in.    fig.set_size_inches(neww,newh)

Things worth noting:

  • Once you call set_axes_locator() on an axis instance you break the tight_layout() function.
  • The original figure size you choose will be irrelevent, and the final figure size is determined by the axes size you choose and the size of the labels/tick labels/outward ticks.
  • This approach doesn't work with colour scale bars.
  • This is my first ever stack overflow post.