Colorbars and legends

Axes colorbars and legends

Drawing colorbars and legends is a much smoother experience with ProPlot. To draw a colorbar or legend along the outside of an axes, use the colorbar and legend Axes methods with e.g. loc='right'. If you do this multiple times, the colorbars and legends will be “stacked”. Room for colorbars and legends is allocated from the space between subplot rows and columns – it is no longer stolen from the axes.

To plot data and draw a colorbar in one go, pass an outer location, e.g. colorbar='r' to methods that accept a cmap argument. To draw a legend or colorbar-legend in one go, pass an outer location, e.g. legend='r' or colorbar='r', to methods that accept a cycle argument. These are powered by the cmap_changer and cycle_changer wrappers.

To draw an inset colorbar, pass an inset location, e.g. colorbar='upper right' or colorbar='ur', to methods that accept a cmap or cycle argument. Inset colorbars have optional rectangular backgrounds, just like inset legends.

[1]:
import proplot as plot
import numpy as np
with plot.rc.context(abc=True):
    f, axs = plot.subplots(ncols=2, share=0)
# Colorbars
ax = axs[0]
state = np.random.RandomState(51423)
m = ax.heatmap(state.rand(10, 10), colorbar='t', cmap='dusk')
ax.colorbar(m, loc='r')
ax.colorbar(m, loc='ll', label='colorbar label')
ax.format(title='Axes colorbars', suptitle='Axes colorbars and legends demo')
# Legends
ax = axs[1]
ax.format(title='Axes legends', titlepad='0em')
hs = ax.plot((state.rand(10, 5)-0.5).cumsum(axis=0), lw=3, legend='t', cycle='sharp',
             labels=list('abcde'), legend_kw={'ncols': 5, 'frame': False})
ax.legend(hs, loc='r', ncols=1, frame=False)
ax.legend(hs, loc='ll', label='legend label')
axs.format(xlabel='xlabel', ylabel='ylabel')
_images/colorbars_legends_3_0.svg
[2]:
import proplot as plot
import numpy as np
f, axs = plot.subplots(nrows=2, share=0, axwidth='4cm', panelpad='1em')
axs.format(suptitle='Stacked colorbars demo')
state = np.random.RandomState(51423)
N = 10
for j, ax in enumerate(axs):
    ax.format(xlabel='data', xlocator=np.linspace(
        0, 0.8, 5), title=f'Subplot #{j+1}')
    for i, (x0, y0, x1, y1, cmap, scale) in enumerate(
            ((0, 0.5, 1, 1, 'grays', 0.5),
             (0, 0, 0.5, 0.5, 'reds', 1),
             (0.5, 0, 1, 0.5, 'blues', 2))):
        if j == 1 and i == 0:
            continue
        data = state.rand(N, N)*scale
        x, y = np.linspace(x0, x1, N + 1), np.linspace(y0, y1, N + 1)
        m = ax.pcolormesh(x, y, data, cmap=cmap,
                          levels=np.linspace(0, scale, 11))
        ax.colorbar(m, loc='l', label=f'dataset #{i+1}')
_images/colorbars_legends_4_0.svg

Figure colorbars and legends

To draw a colorbar or legend along the edge of a figure, use the colorbar or legend Figure methods. The colorbar or legend will be aligned between edges of the subplot grid. As with Panel axes, drawing successive colorbars or legends along the same side will “stack” them.

To draw a colorbar or legend beneath particular row(s) and column(s) of the subplot grid, use the row, rows, col, or cols keyword arguments. Pass an integer to draw the colorbar or legend beside a single row or column, or pass a tuple to draw it beside a range of rows or columns.

[3]:
import proplot as plot
import numpy as np
f, axs = plot.subplots(ncols=3, nrows=3, axwidth=1.2)
state = np.random.RandomState(51423)
m = axs.pcolormesh(
    state.rand(20, 20), cmap='grays',
    levels=np.linspace(0, 1, 11), extend='both')[0]
axs.format(suptitle='Figure colorbars and legends demo', abc=True,
           abcloc='l', abcstyle='a.', xlabel='xlabel', ylabel='ylabel')
f.colorbar(m, label='column 1', ticks=0.5, loc='b', col=1)
f.colorbar(m, label='columns 2-3', ticks=0.2, loc='b', cols=(2, 3))
f.colorbar(m, label='stacked colorbar', ticks=0.1, loc='b', minorticks=0.05)
f.colorbar(m, label='colorbar with length <1', ticks=0.1, loc='r', length=0.7)
[3]:
<matplotlib.colorbar.Colorbar at 0x7f6d6871d908>
_images/colorbars_legends_7_1.svg
[4]:
import proplot as plot
import numpy as np
f, axs = plot.subplots(ncols=2, nrows=2, axwidth=1.3,
                       share=0, wspace=0.3, order='F')
data = (np.random.rand(50, 50) - 0.1).cumsum(axis=0)
m = axs[:2].contourf(data, cmap='grays', extend='both')
colors = plot.Colors('grays', 5)
hs = []
state = np.random.RandomState(51423)
for abc, color in zip('ABCDEF', colors):
    h = axs[2:].plot(state.rand(10), lw=3, color=color, label=f'line {abc}')
    hs.extend(h[0])
f.colorbar(m[0], length=0.8, label='colorbar label', loc='b', col=1, locator=5)
f.colorbar(m[0], label='colorbar label', loc='l')
f.legend(hs, ncols=2, center=True, frame=False, loc='b', col=2)
f.legend(hs, ncols=1, label='legend label', frame=False, loc='r')
axs.format(suptitle='Figure colorbars and legends demo',
           abc=True, abcloc='ul', abcstyle='A')
for ax, title in zip(axs, ['2D dataset #1', '2D dataset #2', 'Line set #1', 'Line set #2']):
    ax.format(xlabel='xlabel', title=title)
_images/colorbars_legends_8_0.svg

New colorbar features

The Figure colorbar and Axes colorbar methods are wrapped by colorbar_wrapper, which adds several new features.

You can draw colorbars from lists of colors or lists of artists by passing a list instead of a mappable object – a colormap is constructed from the corresponding colors on-the-fly. To change outline, divider, tick location, tick label, and colorbar label settings, just pass the appropriate keyword arg to colorbar.

[5]:
import proplot as plot
import numpy as np
f, axs = plot.subplots(share=0, ncols=2)
ax = axs[0]
state = np.random.RandomState(51423)
data = 1 + (state.rand(12, 10) - 0.45).cumsum(axis=0)
cycle = plot.Cycle('algae')
hs = ax.plot(data, lw=4, cycle=cycle, colorbar='lr', colorbar_kw={
             'length': '8em', 'label': 'inset colorbar'})
ax.colorbar(hs, loc='t', values=2*np.linspace(0.5, 9.5, 10),
            label='line values', length=0.7, ticks=2)
ax = axs[1]
m = ax.contourf(data.T, extend='both', cmap='algae',
                levels=plot.arange(0, 3, 0.5))
f.colorbar(m, length=1, loc='r', label='moved tick locations',
           tickloc='left', grid=True)
ax.colorbar(m, loc='ul', length=1, tickminor=True, extendrect=True,
            label='inset colorbar', labelcolor='gray7', labelweight='bold',
            linewidth=1, edgecolor='gray7', ticklabelcolor='gray7', alpha=0.5)
axs.format(suptitle='Colorbar formatting demo',
           xlabel='xlabel', ylabel='ylabel', top=False)
_images/colorbars_legends_11_0.svg

New legend features

The Figure legend and Axes legend methods are wrapped by legend_wrapper, which adds several new features.

You can draw legends with centered legend rows, either by passing center=True or by passing list of lists of plot handles. This is accomplished by stacking multiple single-row, horizontally centered legends, then manually adding an encompassing legend frame. You can also modify legend text and handle properties by passing the appropriate keyword arg to legend, and switch between row-major and column-major order for legend entries with the order keyword arg (default is row-major).

[6]:
import proplot as plot
import numpy as np
plot.rc.cycle = 'contrast'
labels = ['a', 'bb', 'ccc', 'dddd', 'eeeee']
f, axs = plot.subplots(ncols=2, span=False, share=1)
hs1, hs2 = [], []
# On-the-fly legends
state = np.random.RandomState(51423)
for i, label in enumerate(labels):
    data = (state.rand(20)-0.45).cumsum(axis=0)
    h1 = axs[0].plot(data, lw=4, label=label, legend='ul',
                     legend_kw={'order': 'F', 'title': 'column major'})  # add to legend in upper left
    hs1.extend(h1)
    h2 = axs[1].plot(data, lw=4, label=label, legend='r', cycle='floral',
                     legend_kw={'ncols': 1, 'frame': False, 'title': 'no frame'})  # add to legend in right panel
    hs2.extend(h2)
# Outer legends
ax = axs[0]
ax.legend(hs1, loc='b', ncols=3, linewidth=2, title='row major', order='C',
          edgecolor='gray4', facecolor='gray2')
ax = axs[1]
ax.legend(hs2, loc='b', ncols=3, center=True, title='centered legend',
          handlelength=1)  # also works!
axs.format(xlabel='xlabel', ylabel='ylabel', suptitle='Legend formatting demo')
_images/colorbars_legends_14_0.svg