Exploring Matplotlib’s Colormaps

Sam Dedes
5 min readFeb 12, 2021

--

This article explores the various colormaps Matplotlib provides, it is intended for readers proficient in Python with exposure to Matplotlib.

Matplotlib is perhaps the most popular plotting package in Python. It is an essential tool for creating visualizations, offers many tools for customization and has thorough documentation (the 3.3.3 release alone has well over 3000 pages of documentation). There are various packages that build on it’s functionality, such as seaborn, ggplot, and it maintains the ability to edit and alter plots made with these packages.

The feature of interest is the ability to use colormaps in Matplotlib. These are color schemes used in various applications, like a colorbar. A colorbar is something that relates the numbers in your plot to the colors of the plot, this is something you might see in a confusion matrix:

Colorbars are a common feature of confusions matrices, this is cmap “afmhot”

While colormaps are essential to colorbars, they can also be useful as a visual aid to contrast values in all kinds of plots. Given a plot (bar, barh, pie, etc.), here are the tools to add a colormap and explore the different options.

As always, ensure you have the essentials imported:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.cm import get_cmap

Here I’ve added get_cmap , this function is an easy way to fetch information about Matplotlib colormaps.

If you don’t have your own, make some dummy data to plot:

labels = [‘One’, ‘Two’, ‘Three’, ‘Four’, ‘Five’, ‘Six’, ‘Seven’, ‘Eight’, ‘Nine’]
data = [i for i in range(1,10)]

Now scale the data, this determines the colors that correspond to the values in your data.

# scale data
denominator = max(data) - min(data)
scaled_data = [(datum-min(data))/denominator for datum in data]

From the documentation, add some colormaps of interest. Here I define it as a dictionary, but a list would do just as well.

# define colormaps
cmaps = {}
cmaps['Sequential (2)'] = ['binary', 'gist_yarg', 'gist_gray', 'gray', 'bone', 'pink', 'spring', 'summer', 'autumn', 'winter', 'cool', 'Wistia', 'hot', 'afmhot', 'gist_heat', 'copper']

Let’s see how the data looks with and without one of these cmaps:

# standard bar chart
fig, ax = plt.subplots()

ax.bar(labels, data)
plt.title('Default');
####################################################################
Returns:
See figure below
Matplotlib’s standard style bar chart

This is the familiar bar chart, which has plenty of applications. Let’s explore what we can do by adding a colormap:

fig, ax = plt.subplots()colors = []
cmap = get_cmap('viridis')
for decimal in scaled_data:
colors.append(cmap(decimal))

ax.bar(labels, data, color=colors)
plt.title('viridis');
####################################################################
Returns:
See figure below
Matplotlib bar chart with ‘viridis’ cmap

This adds some contrast to the numbers, however, it may not be exactly what we’re looking for. So we can go another step further and compare and contrast as many colormaps as we like, but it will take some coding.

For ease of use create a function that plots a colormap given plot information.

def plot_cmap(labels, data, ax, chart_type='bar', cmap=None):
"""
Creates chart of given type and colormap. Must instantiate fig,
ax outside of function.
Parameters:
labels (list): labels for each data point
data (list): data points to be graphed

*kwargs
chart_type (string): name of matplotlib chart type
cmap (string): name of matplotlib colormap to use in plot
Returns:
matplotlib figure of data with labels, colored according to
specified cmap
"""
# scale data for compatibility with cmap
den = max(data) - min(data)
scaled_data = [(datum-min(data))/den for datum in data]

# get colors corresponding to data
colors = []
my_cmap = get_cmap(cmap)

for decimal in scaled_data:
colors.append(my_cmap(decimal))

fig.patch.set_facecolor('white')

try:
getattr(ax, chart_type)(labels, data, color=colors)

except:
getattr(ax, chart_type)(data, labels=labels, colors=colors)

plt.title(cmap)

If you’re breaking down this function and notice getattr() , the thing inside the try, except condition, note this is used to apply a method on ax that was passed as a string.

For example, ax.bar(labels, data) and gettattr(ax, 'bar')(labels, data) are interchangeable.

Yes, that’s a bit dense and perhaps hand-wavy, but ultimately this function does all the scaling, plotting, and styling given just a few parameters.

Verify it yields the same results as the example above:

# plot figure with function
fig, ax = plt.subplots()
plot_cmap(labels, data, ax, chart_type='bar', cmap='viridis')
‘viridis’ example made with user-defined function

Now, if you may be content to plot these one at a time with the function I’ve written above, however you’re very close to comparing multiple cmaps on a single plot. This takes a little work and some clever use of numpy.

Here I rewrite my colormap names to save some space, this could be switched out for any list of cmap names:

# various colormaps to plot
my_colors = cmaps['Sequential (2)']

This is to get the number of subplots, I want my figure to be as close to square as possible for ease of comparison. To do this I find the square root of the number of cmaps I’m comparing and round to find my subplot indices:

# get number of plots
num = len(my_colors)
sqrt_num = num**0.5
# get size of subplot
# rows
m = np.round(sqrt_num)
# columns
n = np.ceil(sqrt_num)
# convert to int's for indexing
m = int(m)
n = int(n)

Create the figure with the indices from above:

# create figure and axis to plot
fig, axarr = plt.subplots(m, n, figsize=(15,15))

Finally, plot the cmaps. This uses integer division and remainder to plot to the proper index. I use plt.tightlayout() to prevent the tickmarks from overlapping:

# plot various cmaps to subplot

for k in range(len(my_colors)):
# find index
i = k//n
j = k%n

# switch to index and plot
plt.sca(axarr[i, j])
plot_cmap(labels, data, axarr[i, j], chart_type=’barh’,\
cmap=my_colors[k])
plt.tight_layout()####################################################################
Returns:
See figure below
Sequential (2) cmaps plotted for comparison

Viola! Here are all the ‘Sequential (2)’ cmaps on display. Simply choose a favorite, or try others from the documentation if none of these are quite right.

--

--

Sam Dedes
Sam Dedes

No responses yet