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

12
我正在尝试使用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()

生成的图表显示:

Scatterplot with types 0, 1 and 2

我也尝试过不使用Pandas,仅使用例如x=X[:,0], y=X[:,1], hue=X[:,2],但结果相同。Seaborn文档对于hue参数的说明如下:

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

但他们没有澄清“分类”是什么意思,行为如何以及有何不同。我还阅读了分类数据绘图教程,但没有找到答案。在数据中使用像'1''2'这样的字符串只会导致错误:
AttributeError: 'str' object has no attribute 'view'

为什么图例中会有额外的“类型”0?并且,之后如何使用更有意义的类别标签?

在阅读分类数据绘图教程时,我发现了这个:

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

这部分解释了正在发生的事情的一部分(并没有解释为什么会有额外的0类别),但即使使用Pandas分类类型也无济于事。添加

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

...将这些数据转换为分类类型,但Seaborn仍然会报错:

TypeError: data type not understood

一个很好的例子,技术上是一个重复的问题,但问题看起来完全不同。 - detly
这个问题在技术上是一个重复的问题,但是其他的问题/答案并没有帮助到我,而这篇文章确实有用! - LudvigH
1个回答

14

在这里,你确实遇到了“数字”着色方式,这意味着seaborn将尝试使用有意义(对于自己来说)的数据子集数量来创建图例。这将至少是3种不同的颜色。

当用一些大的数值,例如900替换数组中的数字2时,情况可能会更加明显。

enter image description here

解决方案是激活“分类”映射,scatterplotlegend参数可以取三个值:

legend: 可选的“brief”,“full”或False
如何绘制图例。如果为“brief”,数值色调和大小变量将用均匀间隔值的样本表示。如果为“full”,则每个组都将在图例中获得一个条目。如果为False,则不添加图例数据并且不绘制图例。

因此,有点令人费解的是,在这种情况下,您可以设置

legend="full"

为每个色调列中的唯一值获取图例条目(因此比使用“简短”少一个条目)。

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

在此输入图片描述

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

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()

在此输入图片描述


2
谢谢!那个“字符串没问题,但如果是数字就不行”的事情完全把我搞糊涂了。 - detly
其实我认为将其关闭为重复问题更好。我在那里的回答更加通用。 - ImportanceOfBeingErnest

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接