Python Seaborn 绘图中的图例标签不正确。

4

enter image description here

上面的图是使用Python中的seaborn制作的。然而,不确定为什么有些图例圆圈填充了颜色,而其他的没有。这是我正在使用的调色板:
sns.color_palette("Set2", 10)

g = sns.factorplot(x='month', y='vae_factor', hue='ad_name', col='crop', data=df_sub_panel,
                   col_wrap=3, size=5, lw=0.5, ci=None, capsize=.2, palette=sns.color_palette("Set2", 10),
                   sharex=False, aspect=.9, legend_out=False)
g.axes[0].legend(fancybox=None)

--编辑:

有没有办法填充这些圆圈?它们未被填充的原因可能是在这个特定的图中没有数据。


1
@ImportanceOfBeingErnest,我正在使用最新版本的seaborn(0.8)和matpltolib(2.0)。 - user308827
2
测试数据呢? - Serenity
8
如果您真的想得到答案,请提供一个 MCVE(最小完整可再现示例)。也就是说,提供一些示例数据和可运行的代码来复现此问题。当我使用 factorplot 绘制具有缺失数据的图时,图例中没有未填充的圆圈。 - ImportanceOfBeingErnest
2
在图例中放置缺失变量有什么意义呢?如果你确实需要它们出现在图例中,那么它们没有填充的区别不是很好吗?这样它们可以很容易地被识别出来。 - TrigonaMinima
5
没有一个可用的示例,无法复现这个问题。 - spacetyper
显示剩余5条评论
1个回答

7

当没有数据时,圆圈不会被填充,我想你已经推断出来了。但可以通过操作图例对象来强制填充。

完整示例:

import pandas as pd
import seaborn as sns

df_sub_panel = pd.DataFrame([
  {'month':'jan', 'vae_factor':50, 'ad_name':'China', 'crop':False},
  {'month':'feb', 'vae_factor':60, 'ad_name':'China', 'crop':False},
  {'month':'feb', 'vae_factor':None, 'ad_name':'Mexico', 'crop':False},
])

sns.color_palette("Set2", 10)

g = sns.factorplot(x='month', y='vae_factor', hue='ad_name', col='crop', data=df_sub_panel,
                   col_wrap=3, size=5, lw=0.5, ci=None, capsize=.2, palette=sns.color_palette("Set2", 10),
                   sharex=False, aspect=.9, legend_out=False)

# fill in empty legend handles (handles are empty when vae_factor is NaN)
for handle in g.axes[0].get_legend_handles_labels()[0]:
  if not handle.get_facecolors().any():
    handle.set_facecolor(handle.get_edgecolors())

legend = g.axes[0].legend(fancybox=None)

sns.plt.show()

重要的部分是在 for 循环中对 legend 中的 handle 对象进行操作。

这将生成:

enter image description here

与原始版本(没有 for 循环)相比:

enter image description here

编辑:由于评论中的建议,现在更少使用 hacky!


1
当没有数据时,不会绘制任何圆。我认为即使问题拒绝提供 [mcve],这里的每个人都会从答案中受益。 - ImportanceOfBeingErnest
1
你不应该通过__dict__访问私有属性。Matplotlib有公共方法可以访问所有这些对象,例如ax.get_legend_handles_labels() - mwaskom
@ImportanceOfBeingErnest,自己制作一个双点数据框进行测试非常容易。如果您想看我使用的那个,请查看答案历史记录。(我将其删除了,因为我认为它混淆了答案而没有增加太多价值,但总体上我同意您的观点。) - keredson
1
嗯,这有点复杂,它返回的句柄实际上是轴中的对象而不是图例中的对象。你需要更改它们,然后再调用 legend - mwaskom
1
如果提供一个最小可复现示例(MCVE)很容易,那么提供数据框也不应该成为问题。 - ImportanceOfBeingErnest
显示剩余2条评论

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