如何调整seaborn countplot实现每类总计数与非零计数的展示
实现方案
原生seaborn.countplot不直接支持你需要的单条带+双计数标注效果,你可以先对数据集做聚合统计后,用seaborn.barplot实现需求,具体步骤如下:
步骤1:导入依赖并构造示例数据集
import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # 构造示例数据集 df3 = pd.DataFrame({'Class' : [1,1, 2 ,2, 2, 3, 3,3], 'check' : [0,1,0,1,0,1,0,1]})
步骤2:聚合统计每个Class的总计数与check=1的计数
# 按Class分组统计对应总样本数和check为1的样本数 stat_df = df3.groupby('Class').agg( total=('check', 'count'), check_1=('check', 'sum') ).reset_index() # 把Class转为字符串类型避免数值排序异常 stat_df['Class'] = stat_df['Class'].astype(str)
聚合后的数据结构如下:
| Class | total | check_1 |
|---|---|---|
| 1 | 2 | 1 |
| 2 | 3 | 1 |
| 3 | 3 | 2 |
步骤3:绘制单条带并标注计数
# 设置绘图风格 sns.set_style('whitegrid') # 绘制总计数条形图,条的长度对应该Class总样本数,用默认蓝色匹配你原来的配色 ax = sns.barplot(data=stat_df, y='Class', x='total', color='#1f77b4') # 循环为每个条添加标注,格式为「总计数(check=1的计数)」,位置在条的右侧 for i, (total, check1) in enumerate(zip(stat_df['total'], stat_df['check_1'])): ax.text(total + 0.05, i, f'{total} ({check1})', va='center', fontsize=12) # 调整x轴范围避免标注被截断 ax.set_xlim(0, stat_df['total'].max() + 0.5) # 自定义轴标签 ax.set_xlabel('总计数') ax.set_ylabel('Class') plt.show()
运行上述代码即可实现你要的效果:每个Class对应1个蓝色条,条的长度是该Class的总样本数,条右侧同时标注总计数和check=1的计数。
可选:堆叠条形图效果
如果你想要直观展示check=1的数量在总计数中的占比,可以用堆叠条形图实现,代码如下:
# 额外计算check=0的数量 stat_df['check_0'] = stat_df['total'] - stat_df['check_1'] # 先绘制总长度的蓝色条作为底层 ax = sns.barplot(data=stat_df, y='Class', x='total', color='#1f77b4', label='总计数') # 再绘制上层的橙色条表示check=1的数量 sns.barplot(data=stat_df, y='Class', x='check_1', color='#ff7f0e', label='check=1计数') # 添加标注逻辑和之前一致 for i, (total, check1) in enumerate(zip(stat_df['total'], stat_df['check_1'])): ax.text(total + 0.05, i, f'{total} ({check1})', va='center', fontsize=12) ax.set_xlim(0, stat_df['total'].max() + 0.5) plt.legend() plt.show()
这样橙色部分就是check=1的样本数,蓝色全长是总样本数,展示更直观。
内容的提问来源于stack exchange,提问作者Skittles
相关产品推荐
相关产品推荐

