首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Seaborn散点图设置空心标记而不是填充标记

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

Stack Overflow用户
提问于 2021-02-28 08:46:57
回答 3查看 1.4K关注 0票数 1

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

下面是一个简单的例子:

代码语言:javascript
运行
复制
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')

我尝试了以下方法,但都没有成功;大多数方法不会抛出错误,而是生成与上面相同的图。我认为这些不起作用,因为颜色是用

参数,但我不确定修复方法是什么。

代码语言:javascript
运行
复制
with sns.plotting_context(rc={"markerfacecolor": None}):
    sns.scatterplot(data=df, x='x', y='y', hue='cat')
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-02-28 21:25:34

原则上,您应该能够使用以下命令创建圆形标记

,但也有一些

深层并发症

在那里,它目前并不像你希望的那样工作。

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

代码语言:javascript
运行
复制
sns.scatterplot(data=df, x='x', y='y', hue="cat", marker="$\circ$", ec="face", s=100)

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

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

代码语言:javascript
运行
复制
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")

第三种选择是使用

..。这不太灵活,因为绘图必须以自己的图形显示。但它相当简单;另一个答案是

但它有点过度设计,因为它忘记了

参数:

代码语言:javascript
运行
复制
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()

票数 1
EN

Stack Overflow用户

发布于 2021-02-28 10:19:33

我修改了你的代码

如下所示(基于

代码

由@cphlewis提供):

代码语言:javascript
运行
复制
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

x1 = [3,2,5]
y1 = [1,1,2]
x2 = [1,1,0]
y2 = [3,0,2]

df1 = pd.DataFrame({'x1':x1, 'y1':y1})
df2 = pd.DataFrame({'x2':x2, 'y2':y2})

df = pd.concat([df1.rename(columns={'x1':'x','y1':'y'})
                .join(pd.Series(['a']*len(df1), name='df')),
                df2.rename(columns={'x2':'x','y2':'y'})
                .join(pd.Series(['b']*len(df2), name='df'))],
               ignore_index=True)

pal = dict(a="blue", b="red")

g = sns.FacetGrid(df, hue='df', palette=pal, size=5)

g.map(plt.scatter, "x", "y", s=50, alpha=.7,
      linewidth=.5,
      facecolors = 'none',
      edgecolor=['red', 'blue'])

markers = [plt.Line2D([0,0],[0,0], markeredgecolor=pal[key],
                      marker='o', markerfacecolor='none',
                      mew=0.3,
                      linestyle='')
            for key in pal]

plt.legend(markers, pal.keys(), numpoints=1, title="cat")
plt.show()

结果如下:

票数 0
EN

Stack Overflow用户

发布于 2021-02-28 21:47:04

有时

*

,退回到matplotlib功能会更容易:

代码语言:javascript
运行
复制
import matplotlib.pyplot as plt
import pandas as pd

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

fig, ax = plt.subplots()
m_colors = ["blue", "tab:orange", "red", "green"]

for (cat, group), col in zip(df.groupby("cat"), m_colors):
    ax.scatter(group.x, group.y, edgecolors=col, facecolors="none", alpha=0.7, label=cat)

ax.legend(title="empty circles")
plt.show()

示例输出:

*

seaborn和pandas提供了很好的服务。但我看到过很多例子,人们认为“这很容易,所以简单地添加XYZ特性应该很容易”,然后就会得到复杂的代码,如果他们一开始就用基本matplotlib编写代码,那么这些代码就会简单得多。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66404883

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档