Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

Draft Forbes Group Website (Build by Nikola). The official site is hosted at:

https://labs.wsu.edu/forbes

5909 views
License: GPL3
ubuntu2004
Kernel: Python [conda env:work]

Matplotlib Subplot Placement

Here we describe how to local subplots in matplotlib.

import sys sys.exec_prefix

Overview

We start with several figure components that we would like to arrange.

%pylab inline --no-import-all def fig1(): x = np.linspace(0, 1, 100) y = x**2 plt.plot(x, y) plt.xlabel('x'); plt.ylabel('x^2') def fig2(): x = np.linspace(-1, 1, 100) y = x**3 plt.plot(x, y) plt.xlabel('x'); plt.ylabel('x^3')
Populating the interactive namespace from numpy and matplotlib

Here is a typical way of arranging the plots using subplots:

def fig3(): plt.subplot(121) fig1() plt.subplot(122) fig2() fig3()
Image in a Jupyter notebook

Now, what if we want to locate this composite figure? GridSpec is a good way to start. It allows you to generate a SubplotSpec which can be used to locate the components. We first need to update our previous figure-drawing components to draw-themselves in a SubplotSpec. We can reuse our previous functions (which use top-level plt. functions) if we set the active axis.

from functools import partial import matplotlib.gridspec import matplotlib as mpl def fig3(subplot_spec=None): if subplot_spec is None: GridSpec = mpl.gridspec.GridSpec else: GridSpec = partial(mpl.gridspec.GridSpecFromSubplotSpec, subplot_spec=subplot_spec) gs = GridSpec(1, 2) ax = plt.subplot(gs[0, 0]) fig1() ax = plt.subplot(gs[0, 1]) fig2() fig3()
Image in a Jupyter notebook
fig3()
Image in a Jupyter notebook
fig = plt.figure(constrained_layout=True) gs = GridSpec(2, 2, figure=fig) fig3(subplot_spec=gs[0, 0]) fig3(subplot_spec=gs[1, 1])
Image in a Jupyter notebook

Inset Axes

If you want to locate an axis precisely, you can use inset_axes. You can control the location by specifying the transform:

  • bbox_transform=ax.transAxes: Coordinates will be relative to the parent axis.

  • bbox_transform=ax.transData: Coordinates will be relative to the data points in the parent axis.

  • bbox_transform=blended_transform_factory(ax.DataAxes, ax.transAxes): Data coordinates for xx and axis coordinates in yy.

Once this is done, locate the axis by specifying the bounding box and then the location relative to this:

  • bbox_t_anchor=(left, bottom, width, height): Bounding box in the specified coordinate system.

  • loc: Location such as lower left or center.

from matplotlib.transforms import blended_transform_factory blended_transform_factory? #inset_axes?# #trans = transforms.blended_transform_factory( # ax.transData, ax.transAxes)
%pylab inline --no-import-all from mpl_toolkits.axes_grid1.inset_locator import inset_axes ax = plt.subplot(111) plt.axis([0, 2, 0, 2]) inset_axes(ax, width="100%", height="100%", bbox_to_anchor=(0.5, 0.5, 0.5, 0.5), #bbox_transform=ax.transData, loc='lower left', bbox_transform=ax.transAxes, borderpad=0)
Populating the interactive namespace from numpy and matplotlib
<mpl_toolkits.axes_grid1.parasite_axes.AxesHostAxes at 0x11a8ab0f0>
Image in a Jupyter notebook

Here we place subaxes at particular locations along xx.

%pylab inline --no-import-all from mpl_toolkits.axes_grid1.inset_locator import inset_axes from matplotlib.transforms import blended_transform_factory ax = plt.subplot(111) ax.set_xscale('log') ax.set_xlim(0.01, 1000) xs = np.array([0.1, 1, 10,100]) exp_dw = np.exp(np.diff(np.log(xs)).min()/2) for x in xs: inset_axes(ax, width="100%", height="70%", bbox_to_anchor=(x/exp_dw, 0, x*exp_dw-x/exp_dw, 1), #bbox_transform=ax.transData, loc='center', bbox_transform=blended_transform_factory( ax.transData, ax.transAxes), borderpad=0)
Populating the interactive namespace from numpy and matplotlib
Image in a Jupyter notebook
ax = plt.gca() ax.get_xscale()
'linear'
Image in a Jupyter notebook