Skip to content

Instantly share code, notes, and snippets.

@astrofrog
Last active September 10, 2015 07:50
Show Gist options
  • Save astrofrog/8d579ea83e578a9cdb99 to your computer and use it in GitHub Desktop.
Save astrofrog/8d579ea83e578a9cdb99 to your computer and use it in GitHub Desktop.
Preserves the absolute distance from axes to edge of figure. Run and resize the figure, and you will see that the axes are a fixed distance from the edge of the figure. Matplotlib experts: is there a better way to do this?
import matplotlib.pyplot as plt
def FixedMarginAxes(ax_class, margins=[1, 1, 1, 1]):
"""
Class factory to make an axes class that will preserve fixed margins when
figure is resized.
Parameters
----------
ax_class : matplotlib.axes.Axes
The axes class to wrap
margins : iterable
The margins, in inches. The order of the margins is
``[left, right, bottom, top]``
"""
# Note that margins gets used directly in get_fixed_margin_rect and we
# don't pass it through the axes class.
def get_fixed_margin_rect(fig):
fig_width = fig.get_figwidth()
fig_height = fig.get_figheight()
x0 = margins[0] / fig_width
x1 = 1 - margins[1] / fig_width
y0 = margins[2] / fig_height
y1 = 1 - margins[3] / fig_height
dx = max(0.01, x1 - x0)
dy = max(0.01, y1 - y0)
return [x0, y0, dx, dy]
class ax_subclass(ax_class):
def __init__(self, fig, **kwargs):
rect = get_fixed_margin_rect(fig)
super(ax_subclass, self).__init__(fig, rect, **kwargs)
def draw(self, *args, **kwargs):
rect = get_fixed_margin_rect(self.figure)
self.set_position(rect)
super(ax_subclass, self).draw(*args, **kwargs)
return ax_subclass
if __name__ == "__main__":
fig = plt.figure()
ax_class = FixedMarginAxes(plt.Axes, [1, 1, 1, 1])
ax = ax_class(fig)
fig.add_axes(ax)
ax.plot([1, 2, 3])
plt.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment