2015-08-07 15 views
8

Voglio tradurre le etichette di alcuni dati a colori per la rappresentazione grafica con matplotlibmodo elegante per abbinare una stringa in un colore a caso matplotlib

Ho una lista di nomi di ["bob", "joe", "andrew", "pete"]

C'è un costruito in modo mappare queste stringhe con valori di colore in matplotlib? Ho pensato di creare casualmente valori esadecimali, ma potrei ritrovarmi con colori simili o colori non visibili.

Ho provato un paio di modi diversi di cercare di creare valori chiave dal di sotto risposta CMAP:

questo:

#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) 
+0

Vedi anche https://stackoverflow.com/questions/26139423/plot-different-color-for-different-categorical-levels-using-matplotlib – naught101

risposta

18

Scegli un color map, come ad esempio viridis:

cmap = plt.get_cmap('viridis') 

La mappa di colori, cmap, è una funzione che può acquisire una matrice di valori da 0 a 1 e mapparli in colori RGBA. np.linspace(0, 1, len(names)) produce una matrice di numeri equidistanti da 0 a 1 di lunghezza len(names). Così,

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

seleziona i colori dalla mappa viridis colore equidistanti.

Si noti che questo non utilizza il valore della stringa , utilizza solo la posizione ordinale della stringa nella lista per selezionare un colore. Nota anche che questi non sono colori casuali, questo è solo un modo semplice per generare colori unici da un elenco arbitrario di stringhe.


Quindi:

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


Il problema con

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

è che il parametro del cax.scatter Expec ts a sequence di valori RGB (A) della stessa lunghezza di x o un singolo colore. clr è un dict, non una sequenza. Quindi, se colors è la stessa lunghezza x allora si potrebbe utilizzare

ax.scatter(x, y, z, c=colors) 
+0

sto cercando di inserire questi come argomento c in 3d scatter Ho provato zip (nomi, colori) #names è l'elenco di nomi e colori è il cmap # e ho ottenuto un errore in matplotlib. C'è un modo per aggirare questo –

+0

Potresti pubblicare il codice e il messaggio di errore completo di traceback? – unutbu

+0

Ho aggiunto quello che ho cercato di fare trasformandolo in un dizionario –

0

uso la funzione di hash per ottenere numeri compresi tra 0 e 1, è possibile utilizzare questo anche quando non si conoscono tutte le etichette:

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() 
Problemi correlati