问题描述
我有一个 Seaborn 散点图,正在尝试使用“hue_order”控制绘图顺序,但它没有按我预期的那样工作(我无法让蓝点显示在灰色的顶部)。
x = [1,2,3,1,3]
cat = ['N','Y','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',],palette=colors,)
将 'hue_order' 翻转为 hue_order=['N',]
不会改变情节。如何让“Y”类别绘制在“N”类别之上?我的实际数据有重复的 x,y 坐标,这些坐标由类别列区分。
解决方法
TLDR:在绘图之前,对数据进行排序,使主色出现在数据的最后。在这里,它可能只是:
test = test.sort_values('cat') # ascending = True
然后你得到:
似乎 hue_order
不会影响绘制事物的顺序(或 z 顺序)。相反,它会影响颜色的分配方式。例如,如果您没有指定类别到颜色的特定映射(即您只使用颜色列表或调色板),则该参数可以确定是 'N'
还是 'Y'
获得第一个(并获得调色板的第二个)颜色。 hue_order
部分中的 There's an example showing this behavior here。如果 dict
已经将类别链接到颜色 (colors = {'N': 'gray','Y': 'blue'}
),它似乎只会影响图例中标签的顺序,正如您可能已经看到的那样。
所以关键是确保你想要的颜色最后绘制(因此“在上面”)。我还假设 hue_order
参数会按您的预期执行,但显然不是!
发生这种情况的原因是,与大多数绘图函数不同,scatterplot
在构建绘图时不会(内部)迭代色调级别。它绘制单个散点图,然后使用向量设置元素的颜色。这样做是为了使您不会在所有...等之上的倒数第二个色调级别的所有点之上最终得到来自最终色调级别的所有点。但这意味着散点图 z- ordering 对色调排序不敏感,仅反映输入数据中的顺序。
因此您可以使用所需的色调顺序对输入数据进行排序:
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
)
可能有一种更有效的方法来实现熊猫内置的“按唯一值列表排序”;我不确定。