Matplotlib Colormap: Complete Guide to Color Maps in Python
Updated on
Choosing the right colors for a data visualization is deceptively hard. Pick a rainbow colormap and your heatmap looks dramatic -- but the perceptual non-uniformity distorts the data, misleads viewers, and fails entirely for anyone with color-vision deficiency. Use a single-hue palette and subtle patterns vanish into a wall of nearly identical shades. The difference between a chart that reveals insight and one that hides it often comes down to one decision: the colormap.
Matplotlib ships with over 150 built-in colormaps and a flexible API for building your own. The challenge is not a lack of options -- it is knowing which colormap to use, when to use it, and how to customize it for your specific dataset. A poor choice can silently wreck the accuracy of your visualization; the right one makes complex data immediately readable.
This guide covers every practical aspect of Matplotlib colormaps: the four major categories, the most important built-in maps, how to apply them across plot types, how to build custom colormaps from scratch, and how to choose a colormap that is both scientifically accurate and accessible.
What Is a Colormap in Matplotlib?
A colormap is a mapping function that translates scalar data values into colors. Given a number (typically normalized to the 0--1 range), the colormap returns an RGBA color tuple. Matplotlib represents colormaps as objects inheriting from matplotlib.colors.Colormap, and every plotting function that accepts a cmap parameter uses this system under the hood.
import matplotlib.pyplot as plt
import numpy as np
# A colormap is a callable: pass a float in [0, 1], get an RGBA tuple
cmap = plt.colormaps['viridis']
print(cmap(0.0)) # dark purple
print(cmap(0.5)) # teal-green
print(cmap(1.0)) # bright yellowWhen you write plt.imshow(data, cmap='viridis'), Matplotlib normalizes your data to [0, 1] using a Normalize object, then passes each normalized value through the colormap to produce the final pixel colors. Understanding this two-step process -- normalization, then color lookup -- is the key to controlling every aspect of color in your plots. If you are working with subplots, you can apply different colormaps to each panel for comparative visualizations.
The Four Categories of Colormaps
Matplotlib organizes its colormaps into four functional categories. Each serves a different kind of data, and using the wrong category is the single most common colormap mistake.
Sequential Colormaps
Sequential colormaps vary smoothly from light to dark (or dark to light) in a single hue or a narrow hue range. They are designed for data that has a natural ordering from low to high with no special midpoint.
When to use: Temperature readings, population density, elevation, probability, any continuous variable with a meaningful direction.
Key examples: viridis, plasma, inferno, magma, cividis, Blues, Greens, OrRd, YlGnBu
import matplotlib.pyplot as plt
import numpy as np
data = np.random.rand(12, 12)
fig, axes = plt.subplots(1, 3, figsize=(14, 4))
for ax, name in zip(axes, ['viridis', 'plasma', 'inferno']):
im = ax.imshow(data, cmap=name)
ax.set_title(f'Sequential: {name}')
fig.colorbar(im, ax=ax, shrink=0.8)
plt.tight_layout()
plt.show()Diverging Colormaps
Diverging colormaps use two contrasting hues that meet at a neutral midpoint (usually white or light gray). They emphasize deviation in both directions from a central value.
When to use: Temperature anomalies (above/below average), correlation matrices, profit/loss, any data where zero or a midpoint has special meaning.
Key examples: coolwarm, RdBu, RdYlGn, BrBG, PiYG, seismic, bwr
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(42)
data = np.random.randn(10, 10) # Values centered around zero
fig, axes = plt.subplots(1, 3, figsize=(14, 4))
for ax, name in zip(axes, ['coolwarm', 'RdBu', 'seismic']):
im = ax.imshow(data, cmap=name, vmin=-3, vmax=3)
ax.set_title(f'Diverging: {name}')
fig.colorbar(im, ax=ax, shrink=0.8)
plt.tight_layout()
plt.show()Tip: Always set vmin and vmax symmetrically around the midpoint so the neutral color aligns with zero (or your chosen center value).
Qualitative Colormaps
Qualitative colormaps provide a set of visually distinct colors with no implied ordering. Each color is maximally different from its neighbors, making them ideal for categorical labels.
When to use: Cluster labels, categorical scatter plots, bar charts with unordered groups.
Key examples: tab10, tab20, Set1, Set2, Set3, Paired, Accent
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(7)
categories = 6
x = np.concatenate([np.random.randn(30) + i * 3 for i in range(categories)])
y = np.concatenate([np.random.randn(30) + i * 1.5 for i in range(categories)])
labels = np.concatenate([np.full(30, i) for i in range(categories)])
plt.figure(figsize=(9, 6))
scatter = plt.scatter(x, y, c=labels, cmap='tab10', s=50, alpha=0.8, edgecolors='white')
plt.colorbar(scatter, label='Category')
plt.title('Qualitative Colormap: tab10')
plt.xlabel('X')
plt.ylabel('Y')
plt.show()Cyclic Colormaps
Cyclic colormaps start and end at the same color, making them appropriate for data that wraps around -- angles, phases, time of day, wind direction.
When to use: Phase data, compass directions, periodic signals, hours of the day.
Key examples: twilight, twilight_shifted, hsv
import matplotlib.pyplot as plt
import numpy as np
theta = np.linspace(0, 2 * np.pi, 300)
r = np.linspace(0, 1, 300)
T, R = np.meshgrid(theta, r)
Z = T # Color represents angle
fig, ax = plt.subplots(subplot_kw={'projection': 'polar'}, figsize=(6, 6))
im = ax.pcolormesh(T, R, Z, cmap='twilight', shading='auto')
fig.colorbar(im, ax=ax, label='Angle (radians)')
ax.set_title('Cyclic Colormap: twilight')
plt.show()Comparison Table: Colormap Categories
| Category | Purpose | Midpoint Matters? | Ordering? | Best For | Examples |
|---|---|---|---|---|---|
| Sequential | Low-to-high values | No | Yes | Density, temperature, counts | viridis, plasma, inferno, Blues |
| Diverging | Deviation from center | Yes | Yes (both directions) | Anomalies, correlations, profit/loss | coolwarm, RdBu, BrBG |
| Qualitative | Distinct categories | No | No | Labels, clusters, groups | tab10, Set1, Paired |
| Cyclic | Wrapping data | No | Circular | Phase, angle, time of day | twilight, hsv |
Built-In Colormaps Reference
Matplotlib includes colormaps from several families. Here are the most commonly used ones by category.
Perceptually Uniform Sequential
These colormaps were designed so that equal steps in data produce equal steps in perceived brightness. They are the default recommendation for most use cases.
| Colormap | Description | Colorblind Safe |
|---|---|---|
viridis | Purple-to-yellow, Matplotlib default since 2.0 | Yes |
plasma | Purple-to-yellow with higher contrast | Yes |
inferno | Black-to-yellow through red | Yes |
magma | Black-to-white through purple and pink | Yes |
cividis | Blue-to-yellow, optimized for color-vision deficiency | Yes |
Popular Diverging Colormaps
| Colormap | Description | Colorblind Safe |
|---|---|---|
coolwarm | Blue-to-red, smooth transition | Partially |
RdBu | Red-to-blue, strong contrast | No |
RdYlGn | Red-yellow-green | No |
BrBG | Brown-to-teal | Partially |
PiYG | Pink-to-green | Partially |
seismic | Blue-to-red, intense saturation | No |
Using Colormaps Across Plot Types
Heatmaps with imshow
For a higher-level heatmap API with built-in annotations, labels, and masking support, see the seaborn heatmap guide.
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(42)
data = np.random.rand(8, 10)
fig, ax = plt.subplots(figsize=(10, 6))
im = ax.imshow(data, cmap='YlOrRd', aspect='auto')
ax.set_xlabel('Columns')
ax.set_ylabel('Rows')
ax.set_title('Heatmap with YlOrRd Colormap')
fig.colorbar(im, ax=ax, label='Value')
plt.tight_layout()
plt.show()Scatter Plots with Color Encoding
Colormaps are also used extensively in matplotlib scatter plots to encode a third variable as color.
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(42)
n = 300
x = np.random.randn(n)
y = np.random.randn(n)
distance = np.sqrt(x**2 + y**2)
plt.figure(figsize=(8, 6))
sc = plt.scatter(x, y, c=distance, cmap='magma', s=40, alpha=0.8, edgecolors='gray', linewidths=0.3)
plt.colorbar(sc, label='Distance from Origin')
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Scatter Plot with magma Colormap')
plt.show()Contour Plots
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(-3, 3, 200)
y = np.linspace(-3, 3, 200)
X, Y = np.meshgrid(x, y)
Z = np.sin(X) * np.cos(Y)
fig, axes = plt.subplots(1, 2, figsize=(13, 5))
# Filled contour
cf = axes[0].contourf(X, Y, Z, levels=20, cmap='RdBu')
fig.colorbar(cf, ax=axes[0])
axes[0].set_title('contourf with RdBu')
# Line contour with colormap
cl = axes[1].contour(X, Y, Z, levels=15, cmap='plasma')
axes[1].clabel(cl, inline=True, fontsize=8)
axes[1].set_title('contour with plasma')
plt.tight_layout()
plt.show()Pcolormesh for Irregular Grids
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(0)
x = np.linspace(0, 4, 50)
y = np.linspace(0, 3, 40)
X, Y = np.meshgrid(x, y)
Z = np.exp(-(X - 2)**2 - (Y - 1.5)**2) + 0.5 * np.sin(3 * X) * np.cos(3 * Y)
plt.figure(figsize=(9, 6))
pcm = plt.pcolormesh(X, Y, Z, cmap='cividis', shading='auto')
plt.colorbar(pcm, label='Intensity')
plt.xlabel('X')
plt.ylabel('Y')
plt.title('pcolormesh with cividis Colormap')
plt.tight_layout()
plt.show()Colorbar Customization
The colorbar is the legend for your colormap. Customizing it properly is essential for a readable visualization.
Basic Colorbar Options
import matplotlib.pyplot as plt
import numpy as np
data = np.random.rand(10, 10)
fig, ax = plt.subplots(figsize=(8, 6))
im = ax.imshow(data, cmap='viridis')
cbar = fig.colorbar(im, ax=ax, orientation='vertical', shrink=0.8, pad=0.02)
cbar.set_label('Measurement Value', fontsize=12)
cbar.ax.tick_params(labelsize=10)
plt.title('Colorbar Customization')
plt.tight_layout()
plt.show()Discrete Colorbar with BoundaryNorm
When your data naturally falls into discrete bins (risk levels, rating categories), use BoundaryNorm to create sharp color boundaries instead of a smooth gradient.
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
data = np.random.rand(10, 10) * 100
bounds = [0, 20, 40, 60, 80, 100]
norm = mcolors.BoundaryNorm(bounds, ncolors=256)
fig, ax = plt.subplots(figsize=(8, 6))
im = ax.imshow(data, cmap='RdYlGn', norm=norm)
cbar = fig.colorbar(im, ax=ax, ticks=bounds)
cbar.set_label('Score')
ax.set_title('Discrete Colorbar with BoundaryNorm')
plt.tight_layout()
plt.show()Horizontal Colorbar
import matplotlib.pyplot as plt
import numpy as np
data = np.random.rand(8, 12)
fig, ax = plt.subplots(figsize=(10, 5))
im = ax.imshow(data, cmap='plasma')
cbar = fig.colorbar(im, ax=ax, orientation='horizontal', fraction=0.046, pad=0.12)
cbar.set_label('Value')
ax.set_title('Horizontal Colorbar')
plt.tight_layout()
plt.show()Creating Custom Colormaps
When built-in colormaps do not match your needs -- corporate brand colors, domain-specific conventions, or specific perceptual requirements -- Matplotlib provides two classes for building your own.
ListedColormap: From a List of Colors
ListedColormap creates a colormap from an explicit list of colors. Each color occupies an equal portion of the [0, 1] range.
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
# Define colors by name, hex, or RGB tuple
colors = ['#2c3e50', '#2980b9', '#27ae60', '#f39c12', '#e74c3c']
cmap_custom = mcolors.ListedColormap(colors)
data = np.random.rand(10, 10)
fig, ax = plt.subplots(figsize=(8, 6))
im = ax.imshow(data, cmap=cmap_custom)
fig.colorbar(im, ax=ax)
ax.set_title('Custom ListedColormap (5 colors)')
plt.tight_layout()
plt.show()LinearSegmentedColormap: Smooth Gradients
LinearSegmentedColormap creates smooth color transitions. The simplest approach uses from_list, which linearly interpolates between anchor colors.
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
# Smooth gradient from dark blue through white to dark red
colors = ['#1a1a6e', '#4a90d9', '#ffffff', '#d94a4a', '#6e1a1a']
cmap_diverge = mcolors.LinearSegmentedColormap.from_list('custom_diverge', colors)
np.random.seed(42)
data = np.random.randn(12, 12)
fig, ax = plt.subplots(figsize=(8, 6))
im = ax.imshow(data, cmap=cmap_diverge, vmin=-3, vmax=3)
fig.colorbar(im, ax=ax, label='Standard Deviations')
ax.set_title('Custom Diverging Colormap')
plt.tight_layout()
plt.show()Advanced: Segment Dictionary Format
For full control over how each color channel transitions, define a segment dictionary. Each channel (red, green, blue) gets a list of (x, y_left, y_right) tuples specifying anchor points.
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
# Custom colormap: black -> blue -> cyan -> yellow -> white
cdict = {
'red': [(0.0, 0.0, 0.0), (0.25, 0.0, 0.0), (0.5, 0.0, 0.0),
(0.75, 1.0, 1.0), (1.0, 1.0, 1.0)],
'green': [(0.0, 0.0, 0.0), (0.25, 0.0, 0.0), (0.5, 1.0, 1.0),
(0.75, 1.0, 1.0), (1.0, 1.0, 1.0)],
'blue': [(0.0, 0.0, 0.0), (0.25, 1.0, 1.0), (0.5, 1.0, 1.0),
(0.75, 0.0, 0.0), (1.0, 1.0, 1.0)]
}
cmap_seg = mcolors.LinearSegmentedColormap('custom_seg', cdict)
data = np.random.rand(10, 10)
fig, ax = plt.subplots(figsize=(8, 6))
im = ax.imshow(data, cmap=cmap_seg)
fig.colorbar(im, ax=ax)
ax.set_title('Segment Dictionary Colormap')
plt.tight_layout()
plt.show()Registering a Custom Colormap
Register your colormap so it can be referenced by name in any plotting function, just like a built-in:
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
colors = ['#0d0887', '#7e03a8', '#cc4778', '#f89540', '#f0f921']
my_cmap = mcolors.LinearSegmentedColormap.from_list('my_palette', colors)
plt.colormaps.register(cmap=my_cmap)
# Now use it by name anywhere
# plt.imshow(data, cmap='my_palette')Reversing a Colormap
Append _r to any colormap name to get the reversed version. This is useful when you want the visual emphasis inverted -- for example, making higher values darker instead of lighter.
import matplotlib.pyplot as plt
import numpy as np
data = np.random.rand(8, 8)
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
axes[0].imshow(data, cmap='viridis')
axes[0].set_title('viridis (default)')
axes[1].imshow(data, cmap='viridis_r')
axes[1].set_title('viridis_r (reversed)')
plt.tight_layout()
plt.show()Every built-in colormap has a reversed counterpart: plasma_r, coolwarm_r, RdBu_r, inferno_r, and so on.
Truncating and Extracting Colormap Subsets
Sometimes you only need a portion of a colormap. Use Colormap.__call__ with np.linspace and ListedColormap to extract a slice:
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
# Extract the middle 50% of the viridis colormap
full_cmap = plt.colormaps['viridis']
colors = full_cmap(np.linspace(0.25, 0.75, 256))
truncated_cmap = mcolors.ListedColormap(colors)
data = np.random.rand(10, 10)
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
axes[0].imshow(data, cmap='viridis')
axes[0].set_title('Full viridis')
axes[1].imshow(data, cmap=truncated_cmap)
axes[1].set_title('Truncated viridis (25%-75%)')
plt.tight_layout()
plt.show()Normalization: Controlling How Data Maps to Colors
Normalization determines how raw data values are converted to the [0, 1] range before colormap lookup. The default is linear, but Matplotlib offers several alternatives.
| Normalization | Class | When to Use |
|---|---|---|
| Linear | Normalize | Default, evenly distributed data |
| Logarithmic | LogNorm | Data spanning orders of magnitude |
| Symmetric log | SymLogNorm | Data with both signs, log-like scaling |
| Power | PowerNorm | Custom nonlinear compression |
| Two-slope | TwoSlopeNorm | Diverging data with asymmetric ranges |
| Boundary | BoundaryNorm | Discrete bin edges |
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import numpy as np
np.random.seed(42)
data = np.random.lognormal(mean=2, sigma=1.5, size=(20, 20))
fig, axes = plt.subplots(1, 3, figsize=(16, 5))
# Linear (default)
im0 = axes[0].imshow(data, cmap='magma')
fig.colorbar(im0, ax=axes[0])
axes[0].set_title('Linear Normalize')
# LogNorm
im1 = axes[1].imshow(data, cmap='magma', norm=mcolors.LogNorm())
fig.colorbar(im1, ax=axes[1])
axes[1].set_title('LogNorm')
# PowerNorm (gamma=0.5 = square root)
im2 = axes[2].imshow(data, cmap='magma', norm=mcolors.PowerNorm(gamma=0.5))
fig.colorbar(im2, ax=axes[2])
axes[2].set_title('PowerNorm (gamma=0.5)')
plt.tight_layout()
plt.show()Choosing the Right Colormap for Your Data
Picking the right colormap is a design decision with real consequences. Here is a practical decision framework:
-
Is the data sequential (low to high)? Use a sequential colormap. Start with
viridis. If you need higher contrast, tryplasmaorinferno. -
Does the data diverge from a meaningful center? Use a diverging colormap.
coolwarmfor a subtle look,RdBufor strong contrast. Setvminandvmaxsymmetrically. -
Is the data categorical with no ordering? Use a qualitative colormap.
tab10for up to 10 categories,tab20for up to 20. -
Does the data wrap around (angles, phases)? Use a cyclic colormap.
twilightis the best modern option. -
Does the audience include color-vision-deficient viewers? Use
cividis(sequential) orviridis. Avoid red-green pairs likeRdYlGn. -
Will the figure be printed in grayscale? Use
viridis,plasma,inferno, ormagma-- they maintain monotonically increasing lightness.
Accessibility: Colorblind-Friendly Colormaps
Approximately 8% of men and 0.5% of women have some form of color-vision deficiency, most commonly affecting the ability to distinguish red from green. Perceptually uniform colormaps (viridis, plasma, inferno, magma, cividis) were specifically designed to remain readable under the most common forms of color blindness.
Colormaps to avoid for accessibility: jet, rainbow, RdYlGn, RdYlBu (when red-green distinction is critical), hot.
Why jet is harmful: The jet colormap (a rainbow from blue through cyan, green, yellow to red) has perceptual non-uniformities that create false boundaries in the data. Regions that differ by a large amount in actual value can look similar, while small differences near cyan-green can appear dramatic. It also fails completely for viewers with deuteranopia (red-green color blindness).
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(42)
data = np.random.rand(15, 15)
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
axes[0].imshow(data, cmap='jet')
axes[0].set_title('jet (avoid for scientific use)')
axes[1].imshow(data, cmap='cividis')
axes[1].set_title('cividis (colorblind-safe)')
plt.tight_layout()
plt.show()Listing All Available Colormaps
To see every colormap available in your Matplotlib version:
import matplotlib.pyplot as plt
# All colormap names, sorted
all_cmaps = sorted(plt.colormaps())
print(f"Total colormaps: {len(all_cmaps)}")
# Filter out reversed versions
base_cmaps = [c for c in all_cmaps if not c.endswith('_r')]
print(f"Base colormaps (excluding _r): {len(base_cmaps)}")To display them visually:
import matplotlib.pyplot as plt
import numpy as np
gradient = np.linspace(0, 1, 256).reshape(1, -1)
cmaps_to_show = ['viridis', 'plasma', 'inferno', 'magma', 'cividis',
'coolwarm', 'RdBu', 'seismic',
'tab10', 'Set1',
'twilight']
fig, axes = plt.subplots(len(cmaps_to_show), 1, figsize=(10, len(cmaps_to_show) * 0.5))
fig.subplots_adjust(hspace=0.4)
for ax, name in zip(axes, cmaps_to_show):
ax.imshow(gradient, aspect='auto', cmap=name)
ax.set_ylabel(name, rotation=0, labelpad=80, fontsize=10, va='center')
ax.set_xticks([])
ax.set_yticks([])
fig.suptitle('Matplotlib Colormap Samples', fontsize=14, y=1.01)
plt.tight_layout()
plt.show()Interactive Visualization with PyGWalker
When exploring datasets interactively, manually configuring colormaps for every plot can slow you down. PyGWalker (opens in a new tab) is an open-source Python library that turns any pandas or polars DataFrame into a Tableau-style interactive interface directly inside Jupyter. You can drag variables onto axes, assign color encodings, and switch visualization types -- all without writing colormap or plotting code by hand.
import pandas as pd
import pygwalker as pyg
# Load your data
df = pd.read_csv('your_data.csv')
# Launch the interactive UI -- color encoding, binning, and filtering are all point-and-click
walker = pyg.walk(df)This is especially useful during exploratory analysis when you are still deciding which variables to visualize and which color encodings make patterns clearest. Once you find the right visualization, you can always reproduce it in Matplotlib with a precise colormap configuration.
Common Pitfalls and How to Avoid Them
| Pitfall | Problem | Solution |
|---|---|---|
Using jet by default | Perceptual non-uniformity, inaccessible | Switch to viridis or another perceptually uniform map |
| Diverging map for sequential data | Implies a false midpoint | Use a sequential map instead |
| Sequential map for diverging data | Hides the distinction between above/below center | Use a diverging map with symmetric vmin/vmax |
Not setting vmin/vmax on diverging maps | Neutral color may not align with zero | Explicitly set symmetric limits |
| Too many categories with a sequential map | Similar colors are hard to distinguish | Use a qualitative map (tab10, Set1) |
| Ignoring colorblind users | ~8% of male viewers cannot read your plot | Use viridis, cividis, or test with colorblind simulation |
FAQ
What is a colormap in Matplotlib?
A colormap in Matplotlib is a function that maps scalar numerical values to colors. It takes a value between 0 and 1 and returns an RGBA color tuple. Colormaps are used in functions like imshow, scatter, contourf, and pcolormesh to visualize data with color gradients. Access them with plt.colormaps['name'] or pass the name string to the cmap parameter.
How do I choose the right colormap for my data?
For sequential data (low to high), use viridis, plasma, or inferno. For diverging data (deviation from a center), use coolwarm or RdBu. For categorical data, use tab10 or Set1. For cyclic data like angles, use twilight. Always consider accessibility -- viridis and cividis are safe for colorblind viewers.
How do I create a custom colormap in Matplotlib?
Use matplotlib.colors.ListedColormap to create a colormap from a list of specific colors, or use matplotlib.colors.LinearSegmentedColormap.from_list('name', colors) to create a smooth gradient between anchor colors. Register it with plt.colormaps.register() to use it by name.
How do I reverse a colormap in Matplotlib?
Append _r to any colormap name. For example, cmap='viridis_r' gives the reversed version of viridis. This works for all built-in colormaps. For custom colormaps, call the .reversed() method on the colormap object.
Why should I avoid the jet colormap?
The jet colormap has perceptual non-uniformities that create false boundaries and hide real patterns in data. It also fails for viewers with red-green color blindness. Matplotlib changed its default from jet to viridis in version 2.0 specifically because of these problems. Use viridis, plasma, or cividis instead.
How do I add a colorbar to a Matplotlib plot?
Call plt.colorbar(mappable) where mappable is the object returned by imshow, scatter, contourf, or similar functions. Customize it with parameters like label, orientation ('horizontal' or 'vertical'), shrink, and pad. You can also access the colorbar's axes with cbar.ax for fine-grained control.
Conclusion
Colormaps are not decorative choices -- they are functional components that determine whether your visualization communicates truthfully or misleads. They directly impact every color-dependent chart you create, from histograms to correlation heatmaps. Matplotlib gives you a large library of built-in colormaps organized into four clear categories (sequential, diverging, qualitative, cyclic), along with the tools to build entirely custom ones when needed. The perceptually uniform family (viridis, plasma, inferno, magma, cividis) should be your default starting point for any sequential data. For diverging data, choose a map like coolwarm or RdBu and always center the neutral color on your data's meaningful midpoint. For categories, reach for tab10 or Set1. And always consider your audience -- using colorblind-friendly colormaps is not optional, it is professional practice.
Related Guides
- Seaborn Heatmap -- apply colormaps to annotated heatmaps using seaborn's high-level
cmapparameter. - Matplotlib Subplots -- use different colormaps across panels in multi-figure layouts.
- Matplotlib Histogram -- color histogram bars based on value using colormaps and patches.
- Matplotlib Scatter Plot -- encode a third variable as color in scatter visualizations.
- Seaborn Pairplot -- seaborn applies colormaps automatically when using KDE contour plots in pair grids.