You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Seaborn优化DataFrame堆叠条形图:提升百分比显示清晰度

问题描述

我有一个包含FCode和各年份数值的DataFrame,目前用Matplotlib绘制堆叠水平条形图,虽然手动计算添加了百分比标签,但可视化效果差,百分比不够突出清晰。想改用Seaborn实现更优的可视化效果,求实现代码。

数据示例

FCode      2017      2018   2019      2020     2021
3   HCPL1     2          85     207      190.    324
0   HCPL2   431          591    724      537     1025
2   HCPL3   59           202    372      422     679
1   HCPL4   188          201    282      322     557

当前Matplotlib代码

plt.rcParams["figure.figsize"] = (25,10)

Test.plot(
    x = 'FunderCode',
    kind = 'barh',
    stacked = True,
    title = 'Stacked Bar Graph',
    mark_right = True)

Test_total = Test["Count_2017"] + Test["Count_2018"] +Test["Count_2019"] + Test["Count_2020"]+ Test["Count_2021"]
Test_rel = Test[Test.columns[1:]].div(Test_total, 0) * 100
  
for n in Test_rel:
    for i, (cs, ab, pc) in enumerate(zip(Test.iloc[:, 1:].cumsum(1)[n], 
                                         Test[n], Test_rel[n])):
        plt.text(cs - ab / 2, i, str(np.round(pc, 1)) + '%', 
                 va = 'center', ha = 'center', rotation = 20, fontsize = 8)
解决方案:Seaborn实现优化的堆叠水平条形图

Seaborn更适配长格式数据,因此先将宽格式DataFrame重塑为长格式,再计算每个类别占对应行的百分比,最后绘制堆叠条形图并添加清晰的百分比标签。

完整代码

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np

# 构造数据
data = {
    'FCode': ['HCPL1', 'HCPL2', 'HCPL3', 'HCPL4'],
    '2017': [2, 431, 59, 188],
    '2018': [85, 591, 202, 201],
    '2019': [207, 724, 372, 282],
    '2020': [190, 537, 422, 322],
    '2021': [324, 1025, 679, 557]
}
Test = pd.DataFrame(data)

# 1. 将宽格式转为长格式
df_long = Test.melt(id_vars='FCode', var_name='Year', value_name='Value')

# 2. 计算每个FCode的总和及对应年份值的百分比
df_long['Total'] = df_long.groupby('FCode')['Value'].transform('sum')
df_long['Percentage'] = (df_long['Value'] / df_long['Total']) * 100

# 3. 设置绘图风格与尺寸
sns.set_style("whitegrid")
plt.figure(figsize=(20, 8))

# 4. 绘制堆叠水平条形图
ax = sns.barplot(
    data=df_long,
    y='FCode',
    x='Value',
    hue='Year',
    palette='viridis',
    orient='h'
)

# 5. 添加清晰的百分比标签
for p in ax.patches:
    width = p.get_width()
    if width == 0:
        continue
    y_pos = p.get_y() + p.get_height() / 2
    # 匹配对应FCode和年份的百分比
    fcode = ax.get_yticklabels()[int(y_pos // 1)].get_text()
    target_row = df_long[(df_long['FCode'] == fcode) & (df_long['Value'] == width)]
    percentage = target_row['Percentage'].values[0]
    # 绘制标签
    ax.text(
        width / 2, y_pos, 
        f'{np.round(percentage, 1)}%', 
        ha='center', va='center',
        fontsize=10, fontweight='bold', color='white'
    )

# 6. 优化图表外观
ax.set_title('各FCode年度数值占比堆叠条形图', fontsize=16, pad=20)
ax.set_xlabel('数值', fontsize=12)
ax.set_ylabel('FCode', fontsize=12)
plt.legend(title='年份', bbox_to_anchor=(1.05, 1), loc='upper left')
sns.despine(left=True, bottom=True)
plt.tight_layout()
plt.show()

核心优化点

  • 数据格式转换:用melt将宽格式转为Seaborn友好的长格式,便于分组处理。
  • 标签可读性提升:将百分比标签用白色粗体字显示在条形中心,避免旋转,视觉更突出。
  • 视觉风格优化:使用viridis调色板,配合白色网格和去边框处理,提升整体美观度。

内容的提问来源于stack exchange,提问作者GGT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 22:15:36