I want to translate the labels of some data to colors for graphing with matplotlib
I have a list of names ["bob", "joe", "andrew", "pete"]
Is there a built in way to map these strings with color values in matplotlib? I thought about randomly creating hex values but I could end up with similar colors or non visible colors.
I've tried a couple different ways of trying to create key values from the below cmap answer:
this:
#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)
To make a custom color, we can create a hexadecimal string. From it, we can make different sets of color representation and can pass into the scatter method to get the desired output.
Using random() function to generate random colors To begin, import the random function in Python to obtain a random color. The variable r stands for red, g stands for green, and b stands for blue. We already know that the RGB format contains an integer value ranging from 0 to 255.
Choose a color map, such as viridis
:
cmap = plt.get_cmap('viridis')
The colormap, cmap
, is a function which can take an array of values from 0 to 1 and map them to RGBA colors. np.linspace(0, 1, len(names))
produces an array of equally spaced numbers from 0 to 1 of length len(names)
. Thus,
colors = cmap(np.linspace(0, 1, len(names)))
selects equally-spaced colors from the viridis
color map.
Note that this is not using the value of the string, it only uses the ordinal position of the string in the list to select a color. Note also 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()
The problem with
clr = {names[i]: colors[i] for i in range(len(names))}
ax.scatter(x, y, z, c=clr)
is that the c
parameter of ax.scatter
expects a sequence of RGB(A)
values of the same length as x
or a single color. clr
is a dict, not a sequence. So
if colors
is the same length as x
then you could use
ax.scatter(x, y, z, c=colors)
I use the hash function to get numbers between 0 and 1, you can use this even when 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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With