InsetPlot Context Manager

Inset plots, where a second set of axes are included within the main axes of a figure, are often used to show either a detail of the main figure, or possibly an overview or a related dataset. Unfortunately, generating insets with matplotlib can be somewhat tricky, as the standard tools to set up and position the inset plot often require additional work to avoid the inset axes clashing with the main axes.

StonerPlot’s InsetPlot context manager is designed to make this easier by tweaking the placement of the inset. It is a wrapper around axes.Axes.inset_axes() with additional logic to adjust the position of the inset:

with InsetPlot() as inset:
    inset.plot(x, y)

This will create an inset that is then automatically placed in the best location within the current axes and occupies 33% of the axes horizontally and vertically. By default, the context manager also manipulates matplotlib.pyplot’s current axes, so that inside the context manager, the current axes are the inset plot and afterwards, they are restored to the original active axes.

Controlling the Inset Location

The context manager takes a loc parameter that defines the location of the inset. These take the same value as for matplotlib.pyplot.legend (for convenience, any hyphens in the location string are replaced with spaces, and everything is lower-cased):

with InsetPlot(loc="lower right") as inset:
    inset.plot(x, y)

Adjusting the Inset Size

The width, height and dimension parameters control the size of the inset axes (note this does not include any axes labels, tick markers, etc.). width and height are floating-point numbers. If dimension is “fraction” (the default), then these floating-point numbers represent the fraction of the parent axes’ size occupied by the inset axes. Thus, the default values are 0.33, or 33%. If dimension is not “fraction,” then the units for width and height are:

with InsetPlot(width=1.1, height=0.7, dimension="inches") as inset:
    inset.plot(x, y)

Control of Axes and Parameters

By default, the parent axes are considered the current axes from the current figure, but the ax parameter can be used to specify different axes:

with InsetPlot(ax=plt.figure(2).gca()) as inset:
    inset.plot(x, y)

As noted above, by default the context manager switches the current axes around so that Pyplot functions will work on the inset inside the context manager:

plt.plot(x_main, y_main)
with InsetPlot():  # Ignore the context manager's return value
    plt.plot(x_inset, y_inset)  # On the inset axes
plt.xlabel("Main X")  # Back on the main axes again
plt.ylabel("Main Y")

Multiple Insets

The automatic placement of insets considers both the main axes’ legend and other insets, and it will attempt to locate the second inset in the best remaining location:

plt.plot(x_main, y_main)
with InsetPlot() as inset_1:
    inset_1.plot(x_inset_1, y_inset_1)
with InsetPlot() as inset_2:
    inset_2.plot(x_inset_2, y_inset_2)