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

使用matplotlib/seaborn绘制分国家的年度份额堆叠柱状图

Pandas+Matplotlib绘制符合要求的堆叠柱状图

你的数据集本身每个年份下的share加和已经是1,不需要额外做归一化计算,直接将数据透视为「年份为行、国家为列」的结构后,调用matplotlib的柱状图接口开启堆叠模式即可,完整可运行代码如下:

import pandas as pd
import matplotlib.pyplot as plt

# 构造原始数据集
data = {'country': ['US', 'DE', 'IT', 'US', 'DE', 'IT', 'US', 'DE', 'IT'],
        'year': [2000,2000,2000,2001,2001,2001,2002,2002,2002],
        'share': [0.5, 0.3, 0.2, 0.6,0.1,0.3,0.4,0.2,0.4]}
df = pd.DataFrame(data)

# 透视转换为堆叠柱状图要求的输入格式
pivot_data = df.pivot(index='year', columns='country', values='share')

# 初始化画布绘图
fig, ax = plt.subplots(figsize=(7, 4))
pivot_data.plot(
    kind='bar',
    stacked=True,
    ax=ax,
    edgecolor='white', # 给不同国家的块加白边区分更清晰
    width=0.6 # 调整柱宽更美观
)

# 基础配置
ax.set_xlabel('年份')
ax.set_ylabel('份额')
ax.set_xticklabels(pivot_data.index, rotation=0) # 年份标签横向显示,不用倾斜
ax.set_ylim(0, 1.05) # 顶部留少量边距
ax.legend(title='国家', bbox_to_anchor=(1.02, 1), loc='upper left') # 图例放图外不遮挡内容

# 可选:给每个色块加中心数值标签
for container in ax.containers:
    ax.bar_label(container, label_type='center', fmt='%.1f')

plt.tight_layout() # 自动调整布局避免标签截断
plt.show()

对应要求的实现逻辑

  • X轴:直接使用透视表的行索引,也就是year字段的唯一值
  • Y轴:直接映射share字段数值,因为每年份份额总和固定为1,三个年份的柱体总高度完全一致
  • 颜色区分:绘图时会自动给不同国家(也就是透视表的不同列)分配差异化的填充色,你也可以传入color参数自定义配色,比如color=['#e41a1c', '#377eb8', '#4daf4a']
  • 总高度一致:原始数据已经满足每年份share和为1的要求,如果后续换数据集出现总和不为1的情况,只需要在透视前加一行df['share'] = df.groupby('year')['share'].transform(lambda x: x/x.sum())做归一化即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.31 00:48:16