Elegant way to match matplotlib string with random color

I want to translate the labels of some data into colors for graphic display using matplotlib

I have a list of names ["bob", "joe", "andrew", "pete"]

Is there a built-in way to match these strings with color values ​​in matplotlib? I was thinking of randomly creating hexadecimal values, but I could get similar colors or invisible colors.

I tried a couple of different ways to try to create key values ​​from the cmap answer below:

 #names is a list of distinct names cmap = plt.get_cmap('cool') colors = cmap(np.linspace(0, 1, len(names))) clr = {names[i]: colors[i] for i in range(len(names))} ax.scatter(x, y, z, c=clr) 
+8
python matplotlib
source share
2 answers

Select a color map , for example viridis :

 cmap = plt.get_cmap('viridis') 

The cmap color palette is a function that can take an array of values ​​from 0 to 1 and display them in RGBA colors. np.linspace(0, 1, len(names)) creates an array of identically spaced numbers from 0 to 1 of length len(names) . Thus,

 colors = cmap(np.linspace(0, 1, len(names))) 

selects colors with the same difference with the viridis color map.

Note that this does not use the value of the string; it only uses the ordinal position of the string in the list to select a color. Also note that these are not random colors; this is just an easy way to generate unique colors from an arbitrary list of strings.


So:

 import numpy as np import matplotlib.pyplot as plt cmap = plt.get_cmap('viridis') names = ["bob", "joe", "andrew", "pete"] colors = cmap(np.linspace(0, 1, len(names))) print(colors) # [[ 0.267004 0.004874 0.329415 1. ] # [ 0.190631 0.407061 0.556089 1. ] # [ 0.20803 0.718701 0.472873 1. ] # [ 0.993248 0.906157 0.143936 1. ]] x = np.linspace(0, np.pi*2, 100) for i, (name, color) in enumerate(zip(names, colors), 1): plt.plot(x, np.sin(x)/i, label=name, c=color) plt.legend() plt.show() 

enter image description here


A problem with

 clr = {names[i]: colors[i] for i in range(len(names))} ax.scatter(x, y, z, c=clr) 

the c ax.scatter parameter expects a sequence RGB (A) of the same length as x , or the same color. clr is a dict, not a sequence. So if colors is the same length as x , then you can use

 ax.scatter(x, y, z, c=colors) 
+18
source share

I use a hash function to get numbers between 0 and 1, you can use this even if you don't know all the labels:

 x = [1, 2, 3, 4, 5] labels = ["a", "a", "b", "b", "a"] y = [1, 2, 3, 4, 5] colors = [float(hash(s) % 256) / 256 for s in labels] plt.scatter(x, y, c=colors, cmap="jet") plt.show() 
0
source share

All Articles