Seaborn 散点图无法 hue_order 工作

Seaborn scatterplot can't get hue_order to work

我有一个 Seaborn 散点图,我试图用 'hue_order' 来控制绘图顺序,但它没有像我预期的那样工作(我无法让蓝点显示在灰色)。

x = [1, 2, 3, 1, 2, 3]
cat = ['N','Y','N','N','N']
test = pd.DataFrame(list(zip(x,cat)), 
                  columns =['x','cat']
                 )
display(test)

colors = {'N': 'gray', 'Y': 'blue'}
sns.scatterplot(data=test, x='x', y='x', 
                hue='cat', hue_order=['Y', 'N', ],
                palette=colors,
               )

将 'hue_order' 翻转为 hue_order=['N', 'Y', ] 不会改变情节。如何让 'Y' 类别绘制在 'N' 类别之上?我的实际数据有重复的 x,y 坐标,按类别列区分。

TLDR:在绘图之前,对数据进行排序,使主色出现在数据的最后。在这里,它可能只是:

test = test.sort_values('cat') # ascending = True

然后你得到:


似乎 hue_order 不会影响绘图的顺序(或 z 顺序)。相反,它会影响颜色的分配方式。例如,如果您没有指定类别到颜色的特定映射(即您只使用颜色列表或调色板),则此参数可以确定 'N''Y' 是否获得第一个(并获得调色板的第二个)颜色。 There's an example showing this behavior herehue_order 部分。当您 dict 已经将类别链接到颜色 (colors = {'N': 'gray', 'Y': 'blue'}) 时,它似乎只会影响图例中标签的顺序,正如您可能已经看到的那样。

所以关键是要确保你想要的颜色最后绘制(因此“在顶部”)。我还假设 hue_order 参数会按照您的预期执行,但显然不是!

发生这种情况的原因是,与大多数绘图函数不同,scatterplot 在构建绘图时不会(内部)迭代色调级别。它绘制单个散点图,然后使用向量设置元素的颜色。它这样做是为了让您不会将最终色调级别的所有点都放在倒数第二个色调级别的所有点之上...等等。但这意味着散点图 z-排序对色调排序不敏感,仅反映输入数据中的顺序。

因此您可以使用所需的色调顺序对输入数据进行排序:

hue_order = ["N", "Y"]
colors = {'N': 'gray', 'Y': 'blue'}
sns.scatterplot(
    data=test.sort_values('cat', key=np.vectorize(hue_order.index)),
    x='x', y='x',
    hue='cat', hue_order=hue_order,
    palette=colors, s=100,  # Embiggen the points to see what's happening
)

pandas 中内置的“按唯一值列表排序”可能有更有效的方法;我不确定。