Jürg W. Spaak
Jürg W. Spaak

Reputation: 2139

Create a colorbar without a mappable in matplotlib

To call plt.colorbar I need a "mappable", which I usually create by plt.imshow or plt.contour. Is there a "reasonable" way to create a mappable without these?

More specifically, my code is as follows:

import matplotlib.pyplot as plt
from matplotlib.cm import viridis

colors = viridis(np.linspace(0,1,10))
for i, col in enumerate(colors):
    plt.plot(i, 'o', color = col)

I would then like to call plt.colorbar, but I don't have a mappable. My usual work around is cmap = plt.scatter(np.linspace(0,1), np.full(50, np.nan), c = np.linspace(0,1)), which works perfectly well, but I find utterly ugly.

Upvotes: 1

Views: 3598

Answers (2)

Léonard
Léonard

Reputation: 2630

In that case, you can use scatter not only for generating the mappable, but doing all the job at once (plotting the dots, and returning the corresponding mappable).

EDIT

In general, Matplotlib always provides a way to make a collection of objects (see for instance the LineCollection usage example) allowing to plot a collection of lines (or any other object) with varying properties like color, line width, etc.

import matplotlib.pyplot as plt
import numpy as np

colors = np.linspace(0,1,10)
mappable = plt.scatter(np.zeros(10), colors, s=30, c=colors, cmap='viridis')
plt.colorbar(mappable)
plt.show()

Which produce the following image

scatter mappable colorbar

Upvotes: 4

Quang Hoang
Quang Hoang

Reputation: 150735

From matplotlib doc, colorbar accepts a ColorMappable object. So we can create such an object with ScalarMappable and Normalize:

from matplotlib.cm import ScalarMappable
from matplotlib.colors import Normalize

colors = viridis(np.linspace(0,1,10))
for i, col in enumerate(colors):
    plt.plot(i, 'o', color = col)

cmappable = ScalarMappable(Normalize(0,1))
plt.colorbar(cmappable)

Output:

enter image description here

Upvotes: 1

Related Questions