64 votes

seaborn distplot / displot avec distributions multiples

J'utilise seaborn pour tracer un graphique de distribution. Je voudrais tracer plusieurs distributions sur le même graphique avec des couleurs différentes :

Voici comment je commence le graphique de distribution :

import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
iris = load_iris()
iris = pd.DataFrame(data= np.c_[iris['data'], iris['target']],columns= iris['feature_names'] + ['target'])

   sepal length (cm)  sepal width (cm)  petal length (cm)  petal width (cm)  target
0                5.1               3.5                1.4               0.2     0.0
1                4.9               3.0                1.4               0.2     0.0
2                4.7               3.2                1.3               0.2     0.0
3                4.6               3.1                1.5               0.2     0.0
4                5.0               3.6                1.4               0.2     0.0

sns.distplot(iris[['sepal length (cm)']], hist=False, rug=True);

enter image description here

El 'target' contient 3 valeurs : 0, 1, 2.

Je voudrais voir un graphique de distribution pour la longueur des sépales, où target ==0 , target ==1 y target ==2 pour un total de 3 parcelles.

1 votes

Pouvez-vous expliquer ce que vous voulez tracer quand la cible est à 0, quand elle est à 1 et quand elle est à 2 ? D'après ce que j'ai compris, vous voulez voir la longueur du sépale pour les rangées avec target==0 dans une couleur, et la même chose dans des couleurs différentes pour des valeurs différentes de target, est-ce correct ?

1 votes

Ne manquez pas cette solution plus récente : stackoverflow.com/a/64027663/1011724 ce qui est beaucoup plus simple en utilisant le nouveau displot fonction.

0 votes

Desde seaborn v0.11.0 voir des réponses plus récentes en utilisant sns.displot qui remplace sns.distplot

56voto

Arda Arslan Points 804

L'important est de trier le cadre de données par valeurs où target est 0 , 1 o 2 .

import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
import seaborn as sns

iris = load_iris()
iris = pd.DataFrame(data=np.c_[iris['data'], iris['target']],
                    columns=iris['feature_names'] + ['target'])

# Sort the dataframe by target
target_0 = iris.loc[iris['target'] == 0]
target_1 = iris.loc[iris['target'] == 1]
target_2 = iris.loc[iris['target'] == 2]

sns.distplot(target_0[['sepal length (cm)']], hist=False, rug=True)
sns.distplot(target_1[['sepal length (cm)']], hist=False, rug=True)
sns.distplot(target_2[['sepal length (cm)']], hist=False, rug=True)

plt.show()

Le résultat ressemble à ça :

enter image description here

Si vous ne savez pas combien de valeurs target peuvent avoir, trouvez les valeurs uniques dans le target puis découpez le cadre de données et ajoutez-le au graphique de manière appropriée.

import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
import seaborn as sns

iris = load_iris()
iris = pd.DataFrame(data=np.c_[iris['data'], iris['target']],
                    columns=iris['feature_names'] + ['target'])

unique_vals = iris['target'].unique()  # [0, 1, 2]

# Sort the dataframe by target
# Use a list comprehension to create list of sliced dataframes
targets = [iris.loc[iris['target'] == val] for val in unique_vals]

# Iterate through list and plot the sliced dataframe
for target in targets:
    sns.distplot(target[['sepal length (cm)']], hist=False, rug=True)

0 votes

C'est très utile. Merci beaucoup. Que faire si je ne sais pas combien de valeurs distinctes se trouvent dans la colonne "cible" ?

0 votes

Vous pouvez trouver les valeurs uniques dans le target colonne avec : unique_vals = iris['target'].unique()) . À partir de là, vous pouvez configurer des boucles for pour découper le cadre de données et l'insérer dans le graphique.

15 votes

AttributeError : le module 'seaborn' n'a pas d'attribut 'plt' et n'est même pas affiché

50voto

Abbas Points 108

Une approche plus courante pour ce type de problèmes consiste à refondre vos données en format long à l'aide de melt, puis à laisser map faire le reste.

import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
import seaborn as sns

iris = load_iris()
iris = pd.DataFrame(data=np.c_[iris['data'], iris['target']], 
                    columns=iris['feature_names'] + ['target'])

# recast into long format 
df = iris.melt(['target'], var_name='cols',  value_name='vals')

df.head()

   target               cols  vals
0     0.0  sepal length (cm)   5.1
1     0.0  sepal length (cm)   4.9
2     0.0  sepal length (cm)   4.7
3     0.0  sepal length (cm)   4.6
4     0.0  sepal length (cm)   5.0

Vous pouvez maintenant tracer simplement en créant une FacetGrid et en utilisant map :

g = sns.FacetGrid(df, col='cols', hue="target", palette="Set1")
g = (g.map(sns.distplot, "vals", hist=False, rug=True))

enter image description here

5 votes

Merci de partager. C'est génial ! Je n'ai pas obtenu la légende pour 'target'. J'ai ajouté ce morceau de code : g.add_legend()

0 votes

Comment pourrait-on modifier cette méthode pour l'adapter à une fonction de densité spécifique ? Apparemment, le paramètre "fit" de distplot n'est pas transmis.

0 votes

Comment l'axe des y peut-il être compris entre 0 et 1 alors que les valeurs sont supérieures à cette valeur ?

27voto

Amit Amola Points 1415

Si vous essayez de construire le même tracé en utilisant la nouvelle version 0.11.0, Seaborn a ou est en train de déprécier distplot et de le remplacer par displot.

Donc la nouvelle version du code serait :

import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
import seaborn as sns

iris = load_iris()
iris = pd.DataFrame(data=np.c_[iris['data'], iris['target']],
                    columns=iris['feature_names'] + ['target'])

sns.displot(data=iris, x='sepal length (cm)', hue='target', kind='kde', fill=True, palette=sns.color_palette('bright')[:3], height=5, aspect=1.5)

enter image description here

9voto

toliveira Points 731

J'ai trouvé une solution plus simple en utilisant FacetGrid sur https://github.com/mwaskom/seaborn/issues/861 por citynorman :

import numpy as np
import pandas as pd
from sklearn.datasets import load_iris
iris = load_iris()
iris = pd.DataFrame(data= np.c_[iris['data'], iris['target']],columns= iris['feature_names'] + ['target'])

g = sns.FacetGrid(iris, hue="target")
g = g.map(sns.distplot, "sepal length (cm)",  hist=False, rug=True)

enter image description here

9voto

Rafael Toledo Points 363

Une option plus récente et plus simple :

sns.displot(data=iris, x='sepal length (cm)', hue='target', kind='kde')

enter image description here

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X