The basics

Figures and subplots

ProPlot works by subclassing the matplotlib Figure and Axes classes. You can generate grids of proplot Axes axes on a proplot Figure using the subplots command.

import proplot as plot
f, axs = plot.subplots(...)
  • Just like matplotlib.pyplot.subplots, you can use subplots without arguments to generate a single-axes subplot or with ncols or nrows to set up simple grids of subplots.

  • Unlike matplotlib.pyplot.subplots, you can also use subplots to draw arbitrarily complex grids using a 2D array of integers. Just think of this array as a “picture” of your figure, where each unique integer corresponds to a unique axes and 0 corresponds to an empty space.

In the below examples, we create subplot grids with subplots and modify the axes using format and subplot_grid. See Formatting subplots and Subplot grids for details.

[1]:
import proplot as plot
import numpy as np
state = np.random.RandomState(51423)
data = 2*(state.rand(100, 5) - 0.5).cumsum(axis=0)

# Simple plot
f, axs = plot.subplots(ncols=2)
axs[0].plot(data, lw=2)
axs[0].format(xticks=20, xtickminor=False)
axs.format(
    suptitle='Simple subplot grid', title='Title',
    xlabel='x axis', ylabel='y axis'
)

# Complex grid
array = [  # the "picture"; 1 == subplot a, 2 == subplot b, etc.
    [1, 1, 2, 2],
    [0, 3, 3, 0],
]
f, axs = plot.subplots(array, axwidth=1.8)
axs.format(
    abc=True, abcloc='ul', suptitle='Complex subplot grid',
    xlabel='xlabel', ylabel='ylabel'
)
axs[2].plot(data, lw=2)

# Really complex grid
array = [  # the "picture"
    [1, 1, 2],
    [1, 1, 6],
    [3, 4, 4],
    [3, 5, 5],
]
f, axs = plot.subplots(array, width=5, span=False)
axs.format(
    suptitle='Really complex subplot grid',
    xlabel='xlabel', ylabel='ylabel', abc=True
)
axs[0].plot(data, lw=2)
/home/docs/checkouts/readthedocs.org/user_builds/proplot/conda/v0.5.0/lib/python3.7/site-packages/proplot/utils.py:105: ProPlotWarning: Rebuilding font cache.
[1]:
(<matplotlib.lines.Line2D at 0x7f51a17154d0>,
 <matplotlib.lines.Line2D at 0x7f51a1707510>,
 <matplotlib.lines.Line2D at 0x7f51a1722510>,
 <matplotlib.lines.Line2D at 0x7f51a1722b90>,
 <matplotlib.lines.Line2D at 0x7f51a1722a10>)
_images/basics_3_2.svg
_images/basics_3_3.svg
_images/basics_3_4.svg

Formatting subplots

Every Axes returned by subplots has a format method. This is your one-stop-shop for changing axes settings. Keyword args passed to format are interpreted as follows.

  1. Any keyword arg matching the name of an rc setting will be applied to the axes using context. If the name has “dots”, simply omit them. See Configuring proplot for details.

  2. Remaining keyword args are passed to the class-specific XYAxes format, ProjAxes format, or PolarAxes format methods.

  3. Still remaining keyword args are passed to the Axes format method. Axes is the base class for all other axes classes. This changes axes titles, a-b-c subplot labeling, and figure titles.

format lets you use simple shorthands for changing all kinds of axes settings at once, instead of the verbose, one-liner setter methods like ax.set_title(), ax.set_xlabel(), and ax.xaxis.tick_params(). It is also integrated with the Locator, Formatter, and Scale constructors, so you don’t have to directly invoke verbose abstract classes. The goal here is to reduce the amount of typing needed for drawing highly customized plots.

[2]:
import proplot as plot
import numpy as np
f, axs = plot.subplots(ncols=2, nrows=2, share=0, tight=True, axwidth=1.7)
state = np.random.RandomState(51423)
axs[0].plot(np.linspace(1, 10, 80), (state.rand(80, 5) - 0.5).cumsum(axis=0))
axs.format(
    suptitle='Format command demo',
    abc=True, abcloc='ul', abcstyle='a.',
    title='Main', ltitle='Left', rtitle='Right',  # different titles
    urtitle='Title A', lltitle='Title B', lrtitle='Title C',  # extra titles
    collabels=['Column label 1', 'Column label 2'], rowlabels=['Row label 1', 'Row label 2'],
    xlabel='x-axis', ylabel='y-axis',
    xlim=(1, 10), xticks=1, xscale='log',
    ylim=(-2, 2), yticks=plot.arange(-2, 2), yticklabels=('a', 'bb', 'c', 'dd', 'e'),
    xtickdir='inout', xtickminor=False,
    ytickloc='both', yticklabelloc='both', ygridminor=True,
    linewidth=0.8, gridlinewidth=0.8, gridminorlinewidth=0.5,
)
_images/basics_6_0.svg

Changing rc settings

A special object named rc is created whenever you import ProPlot. rc can be used to change matplotlib rcParams settings, custom ProPlot rcParamsLong settings, and special rcParamsShort meta-settings, which change lots of rcParams and rcParamsLong settings all at once. See Configuring proplot for details.

To modify a setting for just one subplot, pass it to the Axes format method. To reset everything to the default state, use reset. To temporarily modify settings for a block of code, use context. See the below example.

[3]:
import proplot as plot
import numpy as np

# Update global settings in several different ways
plot.rc.cycle = 'colorblind'
plot.rc.color = 'gray6'
plot.rc.update({'fontname': 'Noto Sans'})
plot.rc['figure.facecolor'] = 'gray3'
plot.rc.axesfacecolor = 'gray4'

# Apply settings to figure with context()
with plot.rc.context({'suptitle.size': 11}, toplabelcolor='gray6', linewidth=1.5):
    f, axs = plot.subplots(ncols=2, aspect=1, width=6, span=False, sharey=2)

# Plot lines
N, M = 100, 6
state = np.random.RandomState(51423)
values = np.arange(1, M+1)
for i, ax in enumerate(axs):
    data = np.cumsum(state.rand(N, M) - 0.5, axis=0)
    lines = ax.plot(data, linewidth=3, cycle='Grays')

# Apply settings to axes with format()
axs.format(
    grid=False, xlabel='x label', ylabel='y label',
    collabels=['Column label 1', 'Column label 2'],
    suptitle='Rc settings demo',
    suptitlecolor='gray7',
    abc=True, abcloc='l', abcstyle='A)',
    title='Title', titleloc='r', titlecolor='gray7'
)
ay = axs[-1].twinx()
ay.format(ycolor='red', linewidth=1.5, ylabel='secondary axis')
ay.plot((state.rand(100) - 0.2).cumsum(), color='r', lw=3)

# Reset persistent modifications from head of cell
plot.rc.reset()
_images/basics_9_0.svg

Subplot grids

Instead of an ndarray of axes, subplots returns a special subplot_grid container. This container behaves like a python list, but lets you call any arbitrary method on multiple axes at once. It supports both 2D indexing (e.g. axs[0,1]) and 1D indexing (e.g. axs[2]), and is row-major by default. Further, slicing a subplot grid (e.g. axs[:,0]) returns another subplot grid.

You can make your own subplot_grid by passing a list of axes to the class. In the below example, the subplot_grid returned by subplots is used to call format on several axes at once.

[4]:
import proplot as plot
import numpy as np
state = np.random.RandomState(51423)
f, axs = plot.subplots(ncols=4, nrows=4, axwidth=1.2)
axs.format(
    xlabel='xlabel', ylabel='ylabel', suptitle='Subplot grid demo',
    grid=False, xlim=(0, 50), ylim=(-4, 4)
)

# Various ways to select subplots in the subplot grid
axs[:, 0].format(color='gray7', facecolor='gray3', linewidth=1)
axs[0, :].format(color='red', facecolor='gray3', linewidth=1)
axs[0].format(color='black', facecolor='gray5', linewidth=1.4)
axs[1:, 1:].format(facecolor='gray1')
for ax in axs[1:, 1:]:
    ax.plot((state.rand(50, 5) - 0.5).cumsum(axis=0), cycle='Grays', lw=2)
_images/basics_12_0.svg