2015-11-05 15 views
6

Vorrei creare un elenco di grafici a scatole con il colore della scatola che dipende dal nome della colonna pata.DataFrame che utilizzo come input.Boxplot Seaborn colore basato su Nome colonna DataFrame

I nomi di colonna contengono stringhe che indicano una condizione sperimentale in base alla quale voglio che la casella del boxplot sia colorata.

Lo faccio per fare i grafici a scatole:

sns.boxplot(data = data.dropna(), orient="h") 
plt.show() 

Questo crea una bella lista dei grafici a scatole con i nomi corretti. Ora voglio dare a ogni boxplot che ha 'prog +, DMSO +' nel suo nome un colore rosso, lasciando il resto come blu.

Ho cercato di creare un dizionario con i nomi di colonna come le chiavi e colori come valori:

color = {} 
for column in data.columns: 
    if 'prog+, DMSO+' in column: 
     color[column] = 'red' 
    else: 
     color[column] = 'blue' 

e quindi utilizzando il dizionario come colore:

sns.boxplot(data = data.dropna(), orient="h", color=color[column]) 
plt.show() 

Questo non funziona, comprensibilmente (c'è nessun ciclo per passare attraverso il dizionario). Quindi faccio un ciclo:

for column in data.columns: 
    sns.boxplot(data = data[column], orient='h', color=color[column]) 
plt.show() 

Questo fa di grafici a scatole di colori diversi ma tutti uno sopra l'altro e senza le etichette corrette. Se potessi in qualche modo mettere questi boxplot bene in una trama l'uno sotto l'altro, sarei quasi in quello che voglio. O c'è un modo migliore?

+0

Bisogna superare il dizionario a 'palette' (colori multipli), senza' color' (uno solo). – mwaskom

risposta

8

È consigliabile utilizzare il parametro palette, che gestisce più colori, anziché color, che gestisce uno specifico. Puoi dare a palette un nome, un elenco ordinato o un dizionario. Quest'ultimo sembra più adatto alla tua domanda:

import seaborn as sns 
sns.set_color_codes() 
tips = sns.load_dataset("tips") 
pal = {day: "r" if day == "Sat" else "b" for day in tips.day.unique()} 
sns.boxplot(x="day", y="total_bill", data=tips, palette=pal) 

enter image description here

+0

Grazie, funziona perfettamente. Ero molto vicino, avevo già provato la tavolozza, ma non avevo mai pensato di dover scorrere le voci in qualche modo. – Freek

7

È possibile impostare il facecolor di singole caselle dopo tutti tracciando in una sola volta, utilizzando ax.artists[i].set_facecolor('r')

Ad esempio:

import seaborn as sns 
import matplotlib.pyplot as plt 
import pandas as pd 

df = pd.DataFrame(
     [[2, 4, 5, 6, 1], 
     [4, 5, 6, 7, 2], 
     [5, 4, 5, 5, 1], 
     [10, 4, 7, 8, 2], 
     [9, 3, 4, 6, 2], 
     [3, 3, 4, 4, 1] 
     ],columns=['bar', 'prog +, DMSO+ 1', 'foo', 'something', 'prog +, DMSO+ 2']) 

ax = sns.boxplot(data=df,orient='h') 

boxes = ax.artists 

for i,box in enumerate(boxes): 
    if 'prog +, DMSO+' in df.columns[i]: 
     box.set_facecolor('r') 
    else: 
     box.set_facecolor('b') 

plt.tight_layout() 
plt.show() 

enter image description here

+0

Questa è una soluzione intelligente, ma inutilmente complicata. – mwaskom

+0

(+1) questo è l'unico modo che ho trovato finora per gestire i singoli colori in riquadri a scatola con i numeri di mare – MaxG

Problemi correlati