如何在带有分类轴的条形图上叠加数据点

How to overlay data points on a barplot with a categorical axis

目标: 我正在尝试使用 Seaborn 在具有多个分组条形图的图中显示单个数据点。

问题: 我尝试用条形图的 catplot 和单个数据点的另一个 catplot 来做到这一点。但是,这会生成 2 个数字:一个是条形图,另一个是单个数据点。

问题:有没有办法用Seaborn在同一张图中显示各个数据点和条形图?

这是我生成 2 个独立数字的代码:

import seaborn as sns
tips = sns.load_dataset("tips")

g = sns.catplot(
    x="sex", 
    y="total_bill", 
    hue="smoker", 
    row="time", 
    data=tips, 
    kind="bar", 
    ci = "sd", 
    edgecolor="black",
    errcolor="black",
    errwidth=1.5,
    capsize = 0.1,
    height=4, 
    aspect=.7,
)

g = sns.catplot(
    x="sex", 
    y="total_bill", 
    hue="smoker", 
    row="time", 
    data=tips, 
    kind="strip", 
    height=4, 
    aspect=.7,
)

输出:

问题:有没有办法用Seaborn在同一张图中显示各个数据点和条形图?

  • seaborn.catplot是图级剧情,不可合并
  • 如下所示,像seaborn.barplotseaborn.stripplot这样的轴级图可以绘制成相同的axes
import seaborn as sns

tips = sns.load_dataset("tips")

ax = sns.barplot(
    x="sex", 
    y="total_bill", 
    hue="smoker", 
    data=tips, 
    ci="sd", 
    edgecolor="black",
    errcolor="black",
    errwidth=1.5,
    capsize = 0.1,
    alpha=0.5
)

sns.stripplot(
    x="sex", 
    y="total_bill", 
    hue="smoker", 
    data=tips, dodge=True, alpha=0.6, ax=ax
)

# remove extra legend handles
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles[2:], labels[2:], title='Smoker', bbox_to_anchor=(1, 1.02), loc='upper left')

  • Figure-level 绘图 (seaborn.catplot) may not be combined, however, it's possible to map an axes-level plot (seaborn.stripplot) 到 figure-level 绘图上。
  • 测试于 python 3.8.11matplotlib 3.4.3seaborn 0.11.2
import seaborn as sns

tips = sns.load_dataset("tips")

g = sns.catplot(
    x="sex", 
    y="total_bill", 
    hue="smoker", 
    row="time", 
    data=tips, 
    kind="bar", 
    ci = "sd", 
    edgecolor="black",
    errcolor="black",
    errwidth=1.5,
    capsize = 0.1,
    height=4, 
    aspect=.7,
    alpha=0.5)

# map data to stripplot
g.map(sns.stripplot, 'sex', 'total_bill', 'smoker', hue_order=['Yes', 'No'], order=['Male', 'Female'],
      palette=sns.color_palette(), dodge=True, alpha=0.6, ec='k', linewidth=1)