如何将Seaborn countplot的Y轴从计数转换为百分比?
将Seaborn Countplot的Y轴从计数转换为百分比
方法1:修改现有Countplot的Y轴刻度
你当前的代码已经实现了柱子上的百分比标注,但Y轴仍显示原始计数。只需在绘制完countplot后,替换Y轴的刻度与标签即可实现需求:
import matplotlib.pyplot as plt import pandas as pd import seaborn as sns sns.set_theme(style='whitegrid') data = { 'x': ['group1', 'group1', 'group2', 'group3', 'group4', 'group4', 'group3', 'group2', 'group4', 'group1', 'group4', 'group3', 'group2', 'group2', 'group1', 'group3', 'group4', 'group4', 'group2', 'group3', 'group1', 'group2', 'group4', 'group2', 'group3', 'group4', 'group1', 'group1', 'group2', 'group1', 'group2', 'group3', 'group4', 'group4', 'group4', 'group4', 'group4', 'group3', 'group1', 'group2', 'group4', 'group2', 'group3', 'group4', 'group2', 'group2', 'group1', 'group3', 'group4', 'group3', 'group1', 'group4', 'group4', 'group4', 'group4', 'group4'] } df = pd.DataFrame(data) total = len(df['x']) # 更简洁的总数计算方式 plt.figure(figsize=(10,6)) ax = sns.countplot(x='x', data=df) # 推荐使用data参数,代码更清晰 # 将Y轴刻度转换为百分比 current_yticks = ax.get_yticks() ax.set_yticks(current_yticks) ax.set_yticklabels(['{:.1f}%'.format((tick / total)*100) for tick in current_yticks]) ax.set_ylabel('百分比') # 优化百分比标注的位置(基于柱子宽度计算中心,适配不同场景) for p in ax.patches: height = p.get_height() percentage = '{:.1f}%'.format(100 * height / total) x_pos = p.get_x() + p.get_width() / 2 ax.annotate(percentage, (x_pos, height), ha='center', va='bottom') plt.show()
关键改动说明:
- 用
len(df['x'])替代float(df['x'].count()),更高效简洁 - 通过
get_yticks()获取当前刻度,转换为百分比后重新设置标签 - 调整标注的X坐标计算逻辑,确保标注始终在柱子正中心
- 添加Y轴标签明确说明为百分比
方法2:直接用Barplot绘制百分比
另一种更直观的思路是先计算每个类别的百分比,再用barplot直接绘制:
import matplotlib.pyplot as plt import pandas as pd import seaborn as sns sns.set_theme(style='whitegrid') data = { 'x': ['group1', 'group1', 'group2', 'group3', 'group4', 'group4', 'group3', 'group2', 'group4', 'group1', 'group4', 'group3', 'group2', 'group2', 'group1', 'group3', 'group4', 'group4', 'group2', 'group3', 'group1', 'group2', 'group4', 'group2', 'group3', 'group4', 'group1', 'group1', 'group2', 'group1', 'group2', 'group3', 'group4', 'group4', 'group4', 'group4', 'group4', 'group3', 'group1', 'group2', 'group4', 'group2', 'group3', 'group4', 'group2', 'group2', 'group1', 'group3', 'group4', 'group3', 'group1', 'group4', 'group4', 'group4', 'group4', 'group4'] } df = pd.DataFrame(data) # 计算每个类别的百分比 percent_df = df['x'].value_counts(normalize=True).reset_index() percent_df.columns = ['x', 'percentage'] percent_df['percentage'] *= 100 plt.figure(figsize=(10,6)) ax = sns.barplot(x='x', y='percentage', data=percent_df) ax.set_ylabel('百分比') # 添加百分比标注 for p in ax.patches: height = p.get_height() ax.annotate('{:.1f}%'.format(height), (p.get_x() + p.get_width()/2, height), ha='center', va='bottom') plt.show()
这种方法直接基于百分比数据绘图,无需后续修改轴刻度,逻辑更清晰,适合需要直接处理百分比数据的场景。
内容的提问来源于stack exchange,提问作者Stephen Okiya
相关产品推荐
相关产品推荐

