Seaborn 散点图设置空心标记而不是填充标记

a11*_*a11 8 python scatter-plot seaborn

使用 Seaborn 散点图,如何将标记设置为空心圆而不是实心圆?

这是一个简单的例子:

import pandas as pd
import seaborn as sns

df = pd.DataFrame(
    {'x': [3,2,5,1,1,0],
     'y': [1,1,2,3,0,2],
     'cat': ['a','a','a','b','b','b']}
)

sns.scatterplot(data=df, x='x', y='y', hue='cat')
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

我尝试过以下方法但没有成功;其中大多数不会抛出错误,而是产生与上面相同的图。我认为这些不起作用,因为颜色是用hue参数设置的,但我不确定修复是什么。

sns.scatterplot(data=df, x='x', y='y', hue='cat', facecolors = 'none')
sns.scatterplot(data=df, x='x', y='y', hue='cat', facecolors = None)
sns.scatterplot(data=df, x='x', y='y', hue='cat', markerfacecolor = 'none')
sns.scatterplot(data=df, x='x', y='y', hue='cat', markerfacecolor = None)

with sns.plotting_context(rc={"markerfacecolor": None}):
    sns.scatterplot(data=df, x='x', y='y', hue='cat')
Run Code Online (Sandbox Code Playgroud)

mwa*_*kom 12

原则上,您应该能够使用 创建圆形标记fillstyle="none",但是存在一些深层的复杂性,并且它目前无法按您希望的方式工作。

最简单的纯seaborn解决方案是利用您可以使用任意乳胶符号作为标记的事实:

sns.scatterplot(data=df, x='x', y='y', hue="cat", marker="$\circ$", ec="face", s=100)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

这在某种程度上是有限的,因为你失去了对圆的厚度的控制。

混合seaborn-matplotlib方法更灵活,但也更麻烦(您需要自己创建图例):

palette = {"a": "C0", "b": "C1"}
kws = {"s": 70, "facecolor": "none", "linewidth": 1.5}

ax = sns.scatterplot(
    data=df, x='x', y='y',
    edgecolor=df["cat"].map(palette),
    **kws,
)
handles, labels = zip(*[
    (plt.scatter([], [], ec=color, **kws), key) for key, color in palette.items()
])
ax.legend(handles, labels, title="cat")
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

第三种选择是使用FacetGrid. 这不太灵活,因为情节必须有自己的图形。但这相当简单;另一个答案使用FacetGrid但它有点过度设计,因为它忘记了hue_kws参数:

palette = ["C0", "C1"]
g = sns.FacetGrid(
    data=df, hue="cat",
    height=4, aspect=1.25,
    hue_kws={"edgecolor": palette},
)
g.map(plt.scatter, "x", "y", facecolor="none", lw=1.5)
g.add_legend()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述