Author avatar

Vivek Kumar

Customizing Colormaps

Vivek Kumar

  • Apr 10, 2019
  • 10 Min read
  • 53 Views
  • Apr 10, 2019
  • 10 Min read
  • 53 Views
Data
matplotlib

Introduction

In this guide, you will learn about the Matplotlib built-in colormaps as well as creating and customizing them as per your needs.

After completing this guide, you will be able to do the following:

  1. Selecting colormaps
  2. Customizing colormaps
  3. Creating colormaps

The Baseline

Throughout this guide we will be using the following libraries:

Syntax

1
2
3
4
# Importing necessary libraries
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
python

Selecting Colormaps

Just like any other Python visualization library, Matplotlib also has many built-in colormaps which are accessible using matplotlib.cm.get_cmap.

We can access the values stored in each colormap, in terms of RGBA values, as shown:

1
2
3
4
5
6
7
# Accessing three values from the Pastel1 colormap
plt.cm.get_cmap('Pastel1', 3).colors

# Output
# array([[ 0.98431373, 0.70588235, 0.68235294, 1. ],
#        [ 0.99607843, 0.85098039, 0.65098039, 1. ],
#        [ 0.94901961, 0.94901961, 0.94901961, 1. ]])
python

As per the available resources, colormaps are often split into several categories based on their function:

ColormapFunctionUsage
SequentialChanges in lightness, and often saturation of color, incrementally, often using a single hueFor representing information that has ordering
DivergingChanges in lightness, and possibly saturation, of two different colors that meet in the middle at an unsaturated colorWhen the information being plotted has a critical middle value, such as topography or when the data deviates around zero
CyclicChanges in lightness of two different colors that meet in the middle and beginning/end at an unsaturated colorFor values that wrap around at the endpoints, such as phase angle, wind direction, or time of day
QualitativeOften are miscellaneous colorsTo represent information which does not have ordering or relationships

Let us learn to implement each one of these colormap through some data:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# Setting the figure size 
fig = plt.figure(figsize=(10, 8))

# Initializing the data
num = 1000
x1 = np.linspace(-0.5,1,num) + (0.5 - np.random.rand(num))
y1 = np.linspace(-5,5,num) + (0.5 - np.random.rand(num))
x2 = np.linspace(-0.5,1,num) + (0.5 - np.random.rand(num))
y2 = np.linspace(5,-5,num) + (0.5 - np.random.rand(num))

# Sequential Colormap
ax1 = fig.add_subplot(221)
ax1.scatter(x1, y1, c=x1, cmap=plt.cm.get_cmap('magma'))
ax1.set_title('Sequential: magma', fontsize=16, weight='bold')

# Diverging Colormap
ax2 = fig.add_subplot(222)
ax2.scatter(x2, y2, c=x2, cmap=plt.cm.get_cmap('coolwarm'))
ax2.set_title('Diverging: coolwarm', fontsize=16, weight='bold')

# Cyclic Colormap
ax3 = fig.add_subplot(223)
ax3.scatter(x1, y1, c=x1, cmap=plt.cm.get_cmap('hsv'))
ax3.set_xlabel('Cyclic: hsv', fontsize=16, weight='bold')

# Qualitative Colormap
ax4 = fig.add_subplot(224)
ax4.scatter(x2, y2, c=x2, cmap=plt.cm.get_cmap('Dark2'))
ax4.set_xlabel('Qualitative: Dark2', fontsize=16, weight='bold')

# Displaying the figure
plt.show()
python

Choosing CM

To get the full list of all the available Matplotlib built-in colormaps, refer here.

Customizing Colormaps

By default, the details of a colormap are obtained from the attached colarbar, as shown:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Setting the figure size
plt.figure(figsize=(8, 5))

# Initializing the data
num = 1000
x = np.linspace(-0.5,1,num) + (0.5 - np.random.rand(num))
y = np.linspace(-5,5,num) + (0.5 - np.random.rand(num))

# Plotting
fig = plt.scatter(x, y, c=x, cmap=plt.cm.get_cmap('Spectral'))
plt.colorbar(fig)

# Labelling the title
plt.title('A figure with colormap and a colorbar', weight='bold', fontsize=18)

# Displaying the plot
plt.show()
python

Colormap

The colorbar in the above figure shows that as the value falls below zero, it tends to become more red, whereas as the value rises upwards it tends to become blue.

However, it is not always necessary to use the predefined colorbar. We can change it as per our needs. We will look at two such scenarios where we can modify the existing colorbar:

  1. Normalizing the continuous colorbar
  2. Setting discrete colorbar

Normalizing the Continuous Colorbar

We can normalize the colorbar in a given range by using matplotlib.colors.Normalize and later using it inside the norm argument of matplotlib.colorbar.ColorbarBase method. Let us use the Pink colormap which falls under the Sequetial category and normalize it in a range of (5, 10):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Setting the figure size 
fig, (ax1, ax2) = plt.subplots(1,2, figsize=(8, 5), gridspec_kw = {'width_ratios':[3, 0.1]})

# Initializing the data
num = 1000
x1 = np.linspace(-0.5,1,num) + (0.5 - np.random.rand(num))
y1 = np.linspace(-5,5,num) + (0.5 - np.random.rand(num))

# Defining Colormap
ax1.scatter(x1, y1, c=x1, cmap=plt.cm.get_cmap('pink'))
ax1.set_title('Normalized colorbar', fontsize=16, weight='bold')

# Defining Colorbar
norm = mpl.colors.Normalize(vmin=5, vmax=10)
mpl.colorbar.ColorbarBase(ax2, cmap=plt.cm.get_cmap('pink'), norm=norm) 

# Displaying the figure
plt.show()
python

Norm

Setting Discrete Colorbar

Sometimes, we may want to set specific intervals in a colorbar to represent the vastness of a particular sample over another. This can, again, be achieved using the matplotlib.colorbar.ColorbarBase method.

Let us take four colors and build a colormap, using them via matplotlib.colors.ListedColormap method and set a bound to each color as 1, 2, 6, 8:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Setting the figure size 
fig, (ax1, ax2) = plt.subplots(1,2, figsize=(8, 5), gridspec_kw = {'width_ratios':[3, 0.1]})

# Initializing the data
num = 1000
x1 = np.linspace(-0.5,1,num) + (0.5 - np.random.rand(num))
y1 = np.linspace(-5,5,num) + (0.5 - np.random.rand(num))

# Initializing colors and building a colormap
cmap = mpl.colors.ListedColormap(['red', 'green', 'blue', 'cyan'])

# Setting the Colormap
ax1.scatter(x1, y1, c=x1, cmap=cmap)
ax1.set_title('A Figure with a Discrete Colorbar', fontsize=16, weight='bold')

# Setting the Discrete Colorbar
bounds = [1, 2, 6, 8]
mpl.colorbar.ColorbarBase(ax2, cmap=cmap,
                                boundaries=[0] + bounds + [10],
                                extend='both',
                                ticks=bounds,spacing='proportional') 

# Displaying the figure
plt.show()
python

Discrete

Creating Colormaps

As we have seen in the last example, we have created our own colormap using four colors via the matplotlib.colors.ListedColormap method. Let us briefly learn how to create our own colormaps using two approaches:

  1. Listed Colormap
  2. Linear Segmented Colormap

Listed Colormap

Since we have already utilized the matplotlib.colors.ListedColormap method by passing a list of color names to form a colormap, let's learn in what other ways can we benefit from this method. First, we can concatenate multiple colormaps together to form a new colormap. Let us concatenate Greys and Blues colormaps together:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Setting the figure size 
fig, (ax1, ax2) = plt.subplots(1,2, figsize=(8, 5), gridspec_kw = {'width_ratios':[3, 0.1]})

# Initializing the data
num = 1000
x = np.linspace(-0.5,1,num) + (0.5 - np.random.rand(num))
y = np.linspace(-5,5,num) + (0.5 - np.random.rand(num))

# Concatenating colormaps
top = plt.cm.get_cmap('Greys', 128)
bottom = plt.cm.get_cmap('Blues', 128)

newcolors = np.vstack((top(np.linspace(0, 1, 128)),
                       bottom(np.linspace(0, 1, 128))))
cmap = mpl.colors.ListedColormap(newcolors, name='GreyBlue')

# Colormap
ax1.scatter(x, y, c=x, cmap=cmap)
ax1.set_title('Concatenated colormaps', fontsize=16, weight='bold')

# Normalized Colorbar
norm = mpl.colors.Normalize(vmin=5, vmax=10)
mpl.colorbar.ColorbarBase(ax2, cmap=cmap, norm=norm) 

# Displaying the figure
plt.show()
python

Conc

Second, we can even create our own colormap by passing the values to a NumPy array and concatenating with any built-in colormap.

Linear Segmented Colormap

Linear Segmented Colormaps specify colormaps using anchor points between which RGB(A) values are interpolated. Let us take an example where we build a colormap using custom colors provided in the list of tuples along with the anchor points corresponding to each color.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Setting the figure size 
fig, (ax1, ax2) = plt.subplots(1,2, figsize=(8, 5), gridspec_kw = {'width_ratios':[3, 0.1]})

# Initializing the data
num = 1000
x = np.linspace(-0.5,1,num) + (0.5 - np.random.rand(num))
y = np.linspace(-5,5,num) + (0.5 - np.random.rand(num))

# Concatenating colormaps
cmap = mpl.colors.LinearSegmentedColormap.from_list('custom', 
                                             [(0,    'red'),
                                              (0.5, 'green'),
                                              (1,    'Orange')], N=126)

# Defining Colormap
ax1.scatter(x, y, c=x, cmap=cmap)
ax1.set_title('Linear Segmented colormaps', fontsize=16, weight='bold')

# Defining Colorbar
norm = mpl.colors.Normalize(vmin=2, vmax=10)
mpl.colorbar.ColorbarBase(ax2, cmap=cmap, norm=norm) 

# Displaying the figure
plt.show()
python

Linear

Conclusion

In this guide, you have learned about selecting the built-in colormaps, customizing them as per your needs, and creating a new colormap through concatenation.

To learn more on Matplotlib you can refer the following guides:

1