web-dev-qa-db-fra.com

Seaborn - changer la couleur de la barre en fonction du nom de la teinte

J'utilise seaborn et pandas pour créer des diagrammes à barres à partir de données différentes (mais liées). Les deux ensembles de données partagent une catégorie commune utilisée comme hue, et en tant que tel, je voudrais m'assurer que dans les deux graphiques, la couleur de la barre pour cette catégorie correspond. Comment puis-je m'y prendre?

Un exemple de base est le suivant:

import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
sns.set_style('darkgrid')
fig, ax = plt.subplots()

a = pd.DataFrame({'Program': ['A', 'A', 'B', 'B', 'Total', 'Total'],
                  'Scenario': ['X', 'Y', 'X', 'Y', 'X', 'Y'],
                  'Duration': [4, 3, 5, 4, 9, 7]})

g = sns.barplot(data=a, x='Scenario', y='Duration',
                hue='Program', ci=None)
plt.tight_layout()
plt.savefig('3 progs.png')

plt.clf()

b = pd.DataFrame({'Program': ['A', 'A', 'B', 'B', 'C', 'C', 'Total', 'Total'],
                  'Scenario': ['X', 'Y', 'X', 'Y', 'X', 'Y', 'X', 'Y'],
                  'Duration': [4, 3, 5, 4, 3, 2, 12, 9]})

g = sns.barplot(data=b, x='Scenario', y='Duration',
                hue='Program', ci=None)
plt.tight_layout()
plt.savefig('4 progs.png')

Produire les deux graphiques: 3 category bar plot4 category bar plot

Dans cet exemple, je voudrais m'assurer que la catégorie Total utilise la même couleur dans les deux graphiques (par exemple noir)

15
asongtoruin

A. en utilisant une liste de couleurs

La solution la plus simple pour vous assurer d'avoir les mêmes couleurs pour les mêmes catégories dans les deux tracés serait de spécifier manuellement les couleurs lors de la création du tracé.

# First bar plot
ax = sns.barplot(data=a, x='Scenario', y='Duration',
                hue='Program', ci=None, palette=["C0", "C1", "k"])

# ...
# Second bar plot
ax2 = sns.barplot(data=b, x='Scenario', y='Duration',
                hue='Program', ci=None,  palette=["C0", "C1","C2", "k"])

La couleur "C2" (la troisième couleur du cycle chromatique) n'est présente que dans le deuxième tracé où existe un programme C.

Utiliser un dictionnaire

Au lieu d'une liste, vous pouvez également utiliser un dictionnaire, mappant les valeurs de la colonne hue aux couleurs.

palette ={"A":"C0","B":"C1","C":"C2", "Total":"k"}

ax = sns.barplot(data=a, x='Scenario', y='Duration', hue='Program', palette=palette)
# ...
ax2 = sns.barplot(data=b, x='Scenario', y='Duration', hue='Program', palette=palette)

Dans les deux cas, la sortie ressemblerait à ceci:
enter image description here

C. dictionnaire automatique

Enfin, vous pouvez créer ce dictionnaire automatiquement à partir des valeurs de la colonne hue. L'avantage ici serait que vous n'avez pas besoin de connaître les couleurs, ni les valeurs dans les trames de données respectives au préalable.

import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
sns.set_style('darkgrid')
fig, ax = plt.subplots()

a = pd.DataFrame({'Program': ['A', 'A', 'B', 'B', 'Total', 'Total'],
                  'Scenario': ['X', 'Y', 'X', 'Y', 'X', 'Y'],
                  'Duration': [4, 3, 5, 4, 9, 7]})
b = pd.DataFrame({'Program': ['A', 'A', 'B', 'B', 'C', 'C', 'Total', 'Total'],
                  'Scenario': ['X', 'Y', 'X', 'Y', 'X', 'Y', 'X', 'Y'],
                  'Duration': [4, 3, 5, 4, 3, 2, 12, 9]})

unique = a["Program"].append(b["Program"]).unique()
palette = dict(Zip(unique, sns.color_palette()))
palette.update({"Total":"k"})

ax = sns.barplot(data=a, x='Scenario', y='Duration',
                hue='Program', ci=None, palette=palette)
plt.tight_layout()
plt.figure()

ax2 = sns.barplot(data=b, x='Scenario', y='Duration',
                hue='Program', ci=None,  palette=palette)
plt.tight_layout()
plt.show()
22