Written and maintained by CASRAI Editorial Board
Last updated
A colorbar is the legend for any figure that encodes numbers as color: an image, a heatmap, a filled contour plot. In Matplotlib, fig.colorbar(im, ax=ax) attaches one to an existing plot, and the keyword arguments decide where it sits, how it is labelled and what happens to values outside the color range. This guide covers the Matplotlib colorbar the way the current documentation (3.11) describes it, with an argument-by-argument table, a worked out-of-range example and a short list of what to report so another lab can reproduce the figure.
What a colorbar is used for in research
A colorbar tells the reader which number each color stands for. Without one, a heatmap of correlations, a map of signal intensity or a contour plot of model error shows relative differences but no values. The scientific figure rules for journal submission and designing effective scientific figures guides cover the wider figure requirements; this page covers the Matplotlib mechanics.
The Matplotlib documentation defines the object precisely. Figure.colorbar draws a colorbar for a “mappable”, which the docs describe as a ColorizingArtist (for example an AxesImage produced by imshow, or a ContourSet). The colorbar reads the colormap and normalization from that mappable, so the bar always matches the plot it belongs to.
Install or access (official source only)
Matplotlib’s installation page gives these commands:
- pip:
python -m pip install -U pipthenpython -m pip install -U matplotlib - conda:
conda install -c conda-forge matplotlib
The page also lists pixi (pixi add matplotlib) and uv (uv add matplotlib). The reference pages quoted are the 3.11.2 documentation; the examples also use NumPy. Official documentation: Figure.colorbar, matplotlib.colorbar.
Step by step: how to add a colorbar in Matplotlib
1. Add a colorbar to an image or heatmap
Keep the object returned by the plotting call, then pass it to fig.colorbar together with the Axes it belongs to. A matplotlib colorbar needs that object; a bare Axes is not enough.
import numpy as np
import matplotlib.pyplot as plt
data = np.random.default_rng(0).normal(size=(20, 20))
fig, ax = plt.subplots()
im = ax.imshow(data, cmap="viridis", vmin=-2, vmax=2)
cbar = fig.colorbar(im, ax=ax, label="z-score")
plt.show()
Without cax, Matplotlib creates a new Axes for the bar and takes the space from the Axes named in ax. If you omit ax, it defaults to the Axes that contains the mappable. label sets “the label on the colorbar’s long axis”.
2. Colorbar with pyplot: plt.colorbar()
The pyplot function has the same signature idea, but the docs note that mappable is “mandatory for the Figure.colorbar method but optional for the pyplot.colorbar function, which sets the default to the current image.” So plt.colorbar() works right after an imshow call, while fig.colorbar() without a mappable raises an error. If the current figure has no image or contour set, plt.colorbar() also fails (see troubleshooting).
3. Place the colorbar: location, orientation and size
The documented keyword arguments, with their defaults:
location: one of'left','right','top','bottom'.orientation:'vertical'or'horizontal'. The docs say it is preferable to setlocation, and incompatible values raise an exception.fraction(default 0.15),shrink(default 1.0),aspect(default 20), andpad(default 0.05 for a vertical bar, 0.15 for a horizontal one).
cbar = fig.colorbar(im, ax=ax, location="bottom", shrink=0.8, pad=0.15)
4. Draw the colorbar into an Axes you control (cax)
Pass cax when you want the bar in a specific Axes, for example an inset or a reserved grid cell. In that case, per the docs, “it determines the size of the colorbar, and shrink and aspect are ignored.”
cax = ax.inset_axes([1.05, 0.0, 0.05, 1.0])
fig.colorbar(im, cax=cax, label="z-score")
5. One shared colorbar for several subplots
The documentation describes ax as “the one or more parent Axes from which space for a new colorbar Axes will be stolen”, and the pyplot reference types it as an Axes, an iterable or a NumPy array of Axes. Passing the whole set of Axes therefore gives one bar for the group. The bar is only meaningful if every panel uses the same color scale, so give all panels the same vmin and vmax (or one shared norm).
fig, axs = plt.subplots(1, 2)
for a in axs:
pc = a.imshow(data, vmin=-2, vmax=2)
fig.colorbar(pc, ax=axs, location="bottom", label="z-score")
6. Label the bar and set ticks and number format
Besides the label argument, the returned Colorbar has a set_label() method, which the Colorbar class documentation lists among its useful public methods. The ticks argument accepts None (ticks are determined automatically), a list of ticks or a Locator. format defaults to a ScalarFormatter and accepts strings such as "%4.2e" or "{x:.2e}".
cbar = fig.colorbar(im, ax=ax, format="{x:.1f}")
cbar.set_label("z-score")
7. Show values outside the color range with extend
extend accepts 'neither', 'both', 'min' or 'max' and makes pointed end(s) on the bar for out-of-range values. The docs add that out-of-range colors are set for a given colormap with its set_under and set_over methods. extendfrac controls the length of the triangles (default 5% of the bar length; 'auto' makes them match the interior boxes) and extendrect=True makes them rectangular.
For a discrete bar, build a BoundaryNorm. In the “Customized Colorbars” tutorial, a discrete bar uses BoundaryNorm with extend='both', and spacing can be 'uniform' (every color gets equal space) or 'proportional' (space proportional to the data interval).
from matplotlib.colors import BoundaryNorm
cmap = plt.get_cmap("viridis")
norm = BoundaryNorm([-2, -1, 0, 1, 2], cmap.N)
im = ax.imshow(data, cmap=cmap, norm=norm)
fig.colorbar(im, ax=ax, extend="both", spacing="proportional")
8. A colorbar with no plot attached
The Colorbar class documentation says that to show a colormap by itself you can create an empty ColorizingArtist, or pass cmap and norm directly instead of a mappable. The tutorial’s call is fig.colorbar(mpl.colorizer.ColorizingArtist(colorizer), ax=ax, orientation='vertical', label='a colorbar label'), where the colorizer wraps a norm and a colormap. Using cax=ax there draws the bar on that Axes; using ax=ax draws it next to it.
Which argument answers which question
| You want to | Use | What the documentation says |
|---|---|---|
| Let Matplotlib make room for the bar | ax= (leave cax unset) |
A new Axes is created and its space is taken from the Axes in ax. |
| Put the bar in an Axes you already made | cax= |
The bar is drawn into that Axes; its size sets the bar size and shrink and aspect are ignored. ax is used only if cax is not set. |
| Put the bar on a side | location= |
Preferred over orientation; incompatible values raise an exception. |
| Make the bar shorter or thinner | shrink, aspect, fraction |
Defaults 1.0, 20 and 0.15. |
| Mark values beyond the color limits | extend= |
Pointed ends for out-of-range values; pair with the colormap’s under and over colors. |
| Change tick positions or labels | ticks= or cbar.set_ticks(...) |
None means automatic; a list or Locator is accepted. |
| Change the number format | format= |
Default ScalarFormatter; strings like "{x:.2e}" work. |
Output and how to read it
fig.colorbar returns a Colorbar instance. On the figure, the bar shows the colormap across the range set by the mappable’s norm. Check these before the figure leaves your desk:
- The scale matches the data you mean to show. If you did not set
vminandvmax, the range is inferred from the data, so two panels drawn separately can use different scales. For panels you want to compare, set the same limits or the same norm and use one bar. - The label says what and in what unit. A bar labelled only with numbers leaves the reader guessing.
- Pointed ends mean clipped values. A triangle at an end means some data fall outside the displayed range; say so in the caption.
- Record the settings. For a figure another group can regenerate, report the colormap name,
vmin/vmaxor the norm and its boundaries, and the Matplotlib version. The computational reproducibility entry explains why such details belong with the code, and figure legends and captions covers what the caption itself must carry.
Troubleshooting
plt.colorbar() fails because there is no image to use
For plt.colorbar() the documentation says the default mappable is the current image, so a figure that holds only line plots, for example after ax.plot(...), gives it nothing to use. Fix: create the plot with imshow, pcolormesh, contourf or similar and pass the returned object to fig.colorbar.
fig.colorbar() says a required positional argument is missing
The mappable argument is mandatory for Figure.colorbar. Pass the object returned by the plot call.
Colorbar raises an error about location and orientation
Setting both location="right" and orientation="horizontal" is an incompatible pair, and the documentation says incompatible values raise an exception. Set only location, as the docs recommend.
The bar makes the plot smaller
That is the documented behavior when cax is not given: the new Axes takes its space from the parent Axes in ax. To keep the main plot size fixed, create the bar’s Axes yourself and pass it as cax.
Free alternatives: other routes to the same colorbar
| Route | How the colorbar is made | Source |
|---|---|---|
fig.colorbar(mappable, ...) |
Explicit; mappable required; returns a Colorbar. |
Matplotlib Figure.colorbar reference |
plt.colorbar(...) |
Mappable optional; defaults to the current image. | Matplotlib pyplot.colorbar reference |
matplotlib.colorbar.Colorbar(ax, ...) |
Draws a colorbar in an existing Axes; accepts cmap and norm in place of a mappable. |
Matplotlib colorbar API reference |
seaborn.heatmap(...) |
Draws a colorbar by default (cbar=True); cbar_kws passes keyword arguments to matplotlib.figure.Figure.colorbar(); cbar_ax supplies the Axes. |
seaborn.heatmap reference |
For a seaborn-based workflow, see heatmap in seaborn; legends for line and scatter plots are a separate object, covered in legend in Matplotlib.
FAQ
How do I add a colorbar in Matplotlib?
Assign the result of imshow, pcolormesh or contourf to a variable, then call fig.colorbar(im, ax=ax). With pyplot, plt.colorbar() uses the current image.
What is the difference between ax and cax in a matplotlib colorbar?
ax names the parent Axes whose space is taken for a new colorbar Axes. cax is an Axes you supply to draw the bar into; when it is set, ax is not used and shrink and aspect are ignored.
How do I put the colorbar on the bottom or make it horizontal?
Use location="bottom" (or "top"). The docs prefer location to orientation.
How do I label a colorbar?
Pass label="text" to fig.colorbar, or call cbar.set_label("text") on the returned object.
How do I share one colorbar across subplots?
Pass all the Axes to ax and give every panel the same vmin and vmax.
How do I make a colorbar without a plot?
Wrap a norm and colormap in a colorizer and pass a ColorizingArtist to fig.colorbar, as in the Customized Colorbars tutorial, or create a Colorbar directly with cmap and norm.
Sources (official documentation)
- Matplotlib 3.11.2, matplotlib.figure.Figure.colorbar, checked 2026-10-29.
- Matplotlib 3.11.2, matplotlib.pyplot.colorbar, checked 2026-10-29.
- Matplotlib 3.11.2, matplotlib.colorbar (Colorbar class), checked 2026-10-29.
- Matplotlib, Customized Colorbars Tutorial, checked 2026-10-29.
- Matplotlib, Installation, checked 2026-10-29.
- seaborn, seaborn.heatmap, checked 2026-10-29.








