Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to construct a color map in seaborn from a list of RGB colors?

I would like to start with a list of RGB colors, and from them construct a color map I can use in seaborn plots. I have found several instructions on how to change the default color map, but that's not what I'm looking for. I would like to construct a color map that I can use in the cmap argument of, for instance, the kdeplot command.

like image 336
bob.sacamento Avatar asked Sep 02 '25 02:09

bob.sacamento


1 Answers

Constructing a matplotlib.colors.ListedColormap from a list of colors is fairly trivial. Here is an example using the first 4 colors in the tableau 20 color palette -

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

# Tableau 20 color palette for demonstration
colors = [(31, 119, 180), (174, 199, 232), (255, 127, 14), (255, 187, 120)]
# Conversion to [0.0 - 1.0] from [0.0 - 255.0]
colors = [(e[0] / 255.0, e[1] / 255.0, e[2] / 255.0) for e in colors]

cmap = ListedColormap(colors)

a = np.outer(np.linspace(0, 1, 20), np.linspace(0, 1, 20))
im = plt.imshow(a, cmap=cmap)
plt.colorbar(im)
plt.show()

enter image description here

However, if you don't already have a gradient in the list of colors (as the above does not) then it might be more useful to use a matplotlib.colors.LinearSegmentedColormap instead. This is a bit more tricky because of the format expected,

[...] segmentdata argument is a dictionary with a set of red, green and blue entries. Each entry should be a list of x, y0, y1 tuples, forming rows in a table [...].
Each row in the table for a given color is a sequence of x, y0, y1 tuples. In each sequence, x must increase monotonically from 0 to 1. For any input value z falling between x[i] and x[i+1], the output value of a given color will be linearly interpolated between y1[i] and y0[i+1]

Such a dictionary can be generated algorithmically by the method in the example below

import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap
from matplotlib import cm

# Tableau 20 color palette for demonstration
colors = [(31, 119, 180), (174, 199, 232), (255, 127, 14), (255, 187, 120)]
colors = [(e[0] / 255.0, e[1] / 255.0, e[2] / 255.0) for e in colors]

nc = len(colors)
c = np.zeros((3, nc, 3))
rgb = ['red', 'green', 'blue']
for idx, e in enumerate(colors):
    for ii in range(3):
        c[ii, idx, :] = [float(idx) / float(nc - 1), e[ii], e[ii]]

cdict = dict(zip(rgb, c))
cmap = LinearSegmentedColormap('tab20', cdict)

a = np.outer(np.linspace(0, 1, 20), np.linspace(0, 1, 20))
im = plt.imshow(a, cmap=cmap)
plt.colorbar(im)
plt.show()

enter image description here

Assuming the input list colors has the proper RGB format.

like image 157
William Miller Avatar answered Sep 04 '25 17:09

William Miller