12 votes

Pourquoi Seaborn crée-t-il une catégorie supplémentaire dans mes données ?

J'essaie de tracer quelques données simples avec Seaborn 0.9.0 sous Python 3.6.5. Les données sont juste deux points avec une classification différente l'un de l'autre. La classification elle-même est simplement 1 o 2 . Cependant, lorsque je le trace avec Seaborn, la légende montre trois types : 0 , 1 y 2 .

import numpy
import seaborn
import pandas
from matplotlib import pyplot

X = numpy.array([
    [-1, -1, 1],
    [1, 1, 2]
])

data = pandas.DataFrame(X, columns=('x','y','type'))

seaborn.scatterplot(data=data, x='x', y='y', hue='type')

pyplot.show()

Le graphique qui en résulte montre :

Scatterplot with types 0, 1 and 2

J'ai également essayé sans Pandas, en utilisant simplement eg. x=X[:,0], y=X[:,1], hue=X[:,2] mais le résultat est le même.

Les documents de Seaborn disent ceci à propos de la hue argument :

Peut être soit catégorique soit numérique, bien que le mappage des couleurs se comporte différemment dans ce dernier cas.

Mais ils ne précisent pas ce que signifie "catégorique", ni quel est le comportement, ni en quoi il est différent. J'ai également lu le tutoriel sur le tracé des données catégorielles mais je n'ai pas trouvé de réponse.

En utilisant des chaînes de caractères comme '1' y '2' dans les données ne fait que provoquer une erreur :

AttributeError: 'str' object has no attribute 'view'

Pourquoi y a-t-il un "type" supplémentaire de 0 dans la légende ? Et, pour plus tard, comment puis-je avoir des étiquettes de catégorie plus significatives ?


Lire le tutoriel sur le tracé des données catégorielles un peu plus, j'ai trouvé ceci :

Si vos données ont un type de données pandas Categorical, l'ordre par défaut des catégories peut y être défini. Si la variable transmise à l'axe catégorique est numérique, les niveaux seront triés. Mais les données sont toujours traitées comme des catégories et dessinées à des positions ordinales sur les axes catégoriels (plus précisément, à 0, 1, ) même si des nombres sont utilisés pour les étiqueter :

Cela explique à moitié ce qui se passe ici (mais pas pourquoi il y a un supplément d'information). 0 category), mais même l'utilisation du type catégorique de Pandas n'aide pas. Ajout de

data['type'] = data['type'].astype('category')

...convertit ces données en type catégorique, mais Seaborn donne toujours une erreur :

TypeError: data type not understood

14voto

ImportanceOfBeingErnest Points 119438

Vous êtes en effet tombé sur un colormapping "numérique" ici, ce qui signifie que seaborn va essayer d'utiliser un nombre significatif (pour lui-même) de sous-ensemble de données pour créer une légende à partir de celles-ci. Ce sera au moins 3 couleurs différentes.

Cela peut devenir plus évident lorsque l'on remplace le nombre 2 dans le tableau avec quelque chose de grand, par exemple 900

enter image description here

La solution ici est en effet d'activer le mapping "catégorique". Le site legend argument de scatterplot peut prendre trois valeurs

legend : "bref", "complet", ou Faux, facultatif
Comment dessiner la légende. Si "bref", les variables numériques de teinte et de taille seront représentées par un échantillon de valeurs régulièrement espacées. Si "complet", chaque groupe aura une entrée dans la légende. Si "False", aucune donnée de légende n'est ajoutée et aucune légende n'est dessinée.

Ainsi, de manière peu intuitive (du moins dans ce cas), vous pouvez définir les paramètres suivants

legend="full"

pour obtenir une entrée de légende pour chaque valeur unique dans la colonne de la teinte (et donc une de moins qu'en utilisant "bref").

seaborn.scatterplot(data=data, x='x', y='y', hue='type', legend="full")

enter image description here

Notez que l'utilisation de chaînes de caractères comme catégories sera fonctionnent, mais ces chaînes ne peuvent pas être converties en chiffres.

import numpy
import seaborn
import pandas
from matplotlib import pyplot

X = numpy.array([
    [-1, -1, "A"],
    [ 1,  1, "B"]])

data = pandas.DataFrame(X, columns=('x','y','type'))

seaborn.scatterplot(data=data, x='x', y='y', hue='type', legend="brief")

pyplot.show()

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