Regrouper les boxplots en seaborn quand input est une DataFrame
j'ai l'intention de tracer plusieurs colonnes dans un pandas dataframe
, tous regroupés par une autre colonne en utilisant groupby
à l'intérieur seaborn.boxplot
. Il y a une bonne réponse ici, pour un problème similaire dans matplotlib
matplotlib: Groupe boxplots mais étant donné le fait que seaborn.boxplot
vient groupby
option j'ai pensé qu'il pourrait être beaucoup plus facile de le faire dans seaborn
.
voici un exemple reproductible qui échoue:
import seaborn as sns
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=['a1', 'a2', 'a3', 'a4', 'b'])
#Plotting by seaborn
sns.boxplot(df[['a1','a2', 'a3', 'a4']], groupby=df.b)
ce que j'obtiens est quelque chose qui ignore complètement groupby
option:
alors que si je fais ceci avec une colonne cela fonctionne grâce à une autre question SO Seaborn groupby pandas Series:
sns.boxplot(df.a1, groupby=df.b)
Donc je voudrais obtenir tous mes colonnes dans une parcelle (toutes les colonnes viennent dans une échelle similaire).
EDIT:
ci-dessus DONC, la question a été modifié et comprend maintenant un "pas propre" réponse à ce problème, mais il ce serait bien si quelqu'un a une meilleure idée pour ce problème.
3 réponses
comme le font remarquer les autres réponses, le boxplot
fonction est limitée à tracer une seule "couche" de boxplots, et le groupby
paramètre n'a d'effet que lorsque l'entrée est une Série et que vous avez une deuxième variable que vous souhaitez utiliser pour bin les observations dans chaque boîte..
Toutefois, vous pouvez accomplir ce que je pense que vous êtes l'espoir pour le factorplot
fonction à l'aide de kind="box"
. Mais, vous devrez d'abord "fondre" le dataframe de l'échantillon dans ce qu'on appelle la forme longue ou le format "ordonné" où chaque colonne représente une variable et chaque ligne est une observation:
df_long = pd.melt(df, "b", var_name="a", value_name="c")
il est Alors très simple de parcelle:
sns.factorplot("a", hue="b", y="c", data=df_long, kind="box")
la fonction groupby de Seaborn prend les séries et non les images, c'est pourquoi elle ne fonctionne pas.
comme un travail autour, vous pouvez faire ceci:
fig, ax = plt.subplots(1,2, sharey=True)
for i, grp in enumerate(df.filter(regex="a").groupby(by=df.b)):
sns.boxplot(grp[1], ax=ax[i])
ça donne :
Notez que df.filter(regex="a")
est équivalent à df[['a1','a2', 'a3', 'a4']]
a1 a2 a3 a4
0 2 4 5 6
1 4 5 6 7
2 5 4 5 5
3 10 4 7 8
4 9 3 4 6
5 3 3 4 4
Espérons que cette aide
Ce n'est pas vraiment mieux que la réponse est lié, mais je pense que la manière d'y parvenir dans seaborn est l'aide de l' FacetGrid
car le paramètre groupby n'est défini que pour les séries passées à la fonction boxplot.
voici un peu de code-le pd.melt
est nécessaire parce que (comme je peux le dire) la cartographie de la facette ne peut prendre que des colonnes individuelles comme paramètres, de sorte que les données doivent être transformées en un "long" format.
g = sns.FacetGrid(pd.melt(df, id_vars='b'), col='b')
g.map(sns.boxplot, 'value', 'variable')