Colorbars and legends¶
Axes colorbars and legends¶
ProPlot includes some awesome improvements to the matplotlib API that make working with colorbars and legends much easier.
With ProPlot, you can draw a colorbar or legend along the outside edge of a subplot with the colorbar
and legend
Axes
methods by selecting an edge location, e.g. loc='right'
. If you add multiple colorbars and legends to the same side, they will be stacked automatically. The space for outer colorbars and legends is allocated from the space between subplot rows and columns – it is no longer stolen from the axes.
You can also use ProPlot to draw colorbars and legends on-the-fly. To plot data and draw a colorbar in one go, pass a location (e.g. colorbar='r'
) to methods that accept a cmap
argument. To draw a legend or colorbar-legend in one go, pass a 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.
You can also draw an inset colorbar by passing 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), linewidth=3,
cycle='sharp', legend='t',
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')
/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.
[2]:
import proplot as plot
import numpy as np
f, axs = plot.subplots(nrows=2, share=0, axwidth='5cm', panelpad='1em')
axs.format(suptitle='Stacked colorbars demo')
state = np.random.RandomState(51423)
N = 10
# Repeat for both axes
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}')
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.4)
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 0x7ff1e050c250>
[4]:
import proplot as plot
import numpy as np
f, axs = plot.subplots(
ncols=2, nrows=2, axwidth=1.7,
share=0, wspace=0.3, order='F'
)
# Plot data
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])
# Add colorbars and legends
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)
New colorbar features¶
The Figure
colorbar
and Axes
colorbar
methods are wrapped by colorbar_wrapper
, which adds several new features.
You can now draw colorbars from lists of colors or lists of artists by passing a list instead of a mappable object. Colorbar minor ticks are now much more robust, and the tick location and formatter arguments are passed through Locator
and Formatter
. The colorbar width and length can be changed with the width
and length
keyword args. Note that colorbar widths are now specified in physical units, which helps prevent drawing colorbars that look “too skinny” or “too fat”.
[5]:
import proplot as plot
import numpy as np
f, axs = plot.subplots(share=0, ncols=2, axwidth=2)
# Colorbars from lines
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': 'from lines'}
)
ax.colorbar(
hs, loc='t', values=2*np.linspace(0.5, 9.5, 10),
label='from lines', length=0.7, ticks=2
)
# Colorbars from a mappable
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='inside ticks',
tickloc='left'
)
ax.colorbar(
m, loc='ul', length=1, tickminor=True, drawedges=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', abovetop=False
)
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 with several keyword args, 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, axwidth=2)
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'}
)
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'}
)
hs2.extend(h2)
# Outer legends
ax = axs[0]
ax.legend(
hs1, loc='b', ncols=3, linewidth=2,title='row major', order='C',
facecolor='gray2'
)
ax = axs[1]
ax.legend(hs2, loc='b', ncols=3, center=True, title='centered rows')
axs.format(xlabel='xlabel', ylabel='ylabel', suptitle='Legend formatting demo')