为什么Seaborn在我的数据中创建一个额外的类别?

det*_*tly 8 python pandas seaborn

我正在尝试在Python 3.6.5下使用Seaborn 0.9.0 绘制一些简单数据。数据只是彼此不同的分类的两个点。分类本身就是12。然而,当我与Seaborn绘制它,图例显示三种类型:012

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()
Run Code Online (Sandbox Code Playgroud)

结果图显示:

类型为0、1和2的散点图

我也没有使用Pandas尝试过,只是使用eg x=X[:,0], y=X[:,1], hue=X[:,2],但是结果是一样的。

Seaborn的文档是这样说的hue

可以是分类的也可以是数字的,尽管颜色映射在后一种情况下的行为会有所不同。

但是他们没有阐明“分类”的含义,行为是什么,或行为如何不同。我还阅读了分类数据绘图教程,但没有找到答案。

在数据中使用像'1'和这样的字符串'2'只会导致错误:

AttributeError: 'str' object has no attribute 'view'
Run Code Online (Sandbox Code Playgroud)

为什么0图例中还有一个额外的“类型” ?而且,稍后,我如何拥有更有意义的类别标签?


通过阅读分类数据绘图教程,我发现:

如果您的数据具有pandas Categorical数据类型,则可以在此处设置类别的默认顺序。如果传递给分类轴的变量看起来是数字,则将对级别进行排序。但是,即使使用数字来标记数据,数据仍被视为分类数据,并在分类轴上的顺序位置(具体是在0、1,...处)绘制:

这一半解释了这里发生的事情(不是为什么会有额外的0类别),但是即使使用Pandas分类类型也无济于事。新增中

data['type'] = data['type'].astype('category')
Run Code Online (Sandbox Code Playgroud)

...将此数据转换为分类类型,但Seaborn仍然给出错误:

TypeError: data type not understood
Run Code Online (Sandbox Code Playgroud)

Imp*_*est 9

您确实在这里遇到了“数字”色彩映射,这意味着seaborn将尝试使用有意义的(本身)数量的数据子集来从中创建图例。这将至少是3种不同的颜色。

当用2大的东西替换数组中的数字时,这可能会变得更加明显,例如900

在此处输入图片说明

解决方案的确是激活“分类”映射。的legend参数scatterplot可以取三个值

legend:“简要”,“完整”或False,可选
如何绘制图例。如果为“简短”,则数字色相和大小变量将以均匀间隔的值的样本表示。如果“满”,每个组将在图例中获得一个条目。如果为False,则不会添加图例数据,也不会绘制图例。

如此(至少在这种情况下),您可以设置

legend="full"
Run Code Online (Sandbox Code Playgroud)

以获得色相列中每个唯一值的图例条目(因此比使用“简要”少一个)。

seaborn.scatterplot(data=data, x='x', y='y', hue='type', legend="full")
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

请注意,将字符串用作类别可以使用,但是这些字符串不能转换为数字。

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()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

  • 谢谢!“字符串还可以,但如果它们是数字的话就不行”这件事完全把我扔了。 (2认同)