matplotlib: color by dict without normalization

Viewed 5858

My goal is is to use a colormap that maps via a dict, a given number to a given color.

However, matplotlib seems to have normalized the number.

For example, I first created a custom colormap use seaborn, and feed it into plt.scatter

import seaborn as sns

colors = ['pumpkin', "bright sky blue", 'light green', 'salmon', 'grey', 'pale grey']
pal = sns.xkcd_palette(colors)
sns.palplot(pal)

palette

from matplotlib import pyplot as plt
from matplotlib.colors import ListedColormap

cmap = ListedColormap(pal.as_hex())
x = [0, 1, 2]
y = [0, 1, 2]
plt.scatter(x, y, c=[0, 1, 2], s=500, cmap=cmap)  # I'd like to get color ['pumpkin', "bright sky blue", 'light green']

but, it gives me color ['pumpkin', 'salmon', 'pale grey']

scatter

In short: colormap:

palette

getting color 0, 1, and 2 (desired):

enter image description here

but matplotlib gives:

enter image description here

2 Answers

A colormap is always normalized between 0 and 1. A scatter plot will by default normalize the values given to the c argument, such that the colormap ranges from the minimum to the maximum value. However, you may of course define your own normalization. In this case it would be vmin=0, vmax=len(colors).

from matplotlib import pyplot as plt
from matplotlib.colors import ListedColormap

colors = ['xkcd:pumpkin', "xkcd:bright sky blue", 'xkcd:light green', 
          'salmon', 'grey', 'xkcd:pale grey']
cmap = ListedColormap(colors)

x = range(3)
y = range(3)
plt.scatter(x, y, c=range(3), s=500, cmap=cmap, vmin=0, vmax=len(colors))

plt.show()

enter image description here

If you specify the colors as a sequence of numbers ([0,1,2] in your case), then those numbers will be mapped to colors using the normalization. You can instead directly specify a sequence of colors:

x = [0, 1, 2]
y = [0, 1, 2]
clrs = [0, 1, 2]
plt.scatter(x, y, c=[pal[c] for c in clrs], s=500)

gives

enter image description here

Related