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

如何制作带百分比标注的堆叠柱状图(Matplotlib实现)

堆叠柱状图实现方案

1. 数据格式转换

原DataFrame是长格式,需先转成宽格式(日期为索引、设备为列),才能直接绘制堆叠柱状图:

pivot_df = df.pivot(index='date', columns='device', values='count')

2. 自定义设备颜色

按需求定义每个设备对应的颜色:

color_map = {'tv': 'red', 'laptop': 'steelblue', 'cellphone': 'limegreen'}

3. 绘制堆叠柱状图

基于透视后的DataFrame绘制,同时配置轴标签、标题和图例:

fig, ax = plt.subplots(figsize=(10, 6))
pivot_df.plot(kind='bar', stacked=True, color=[color_map[col] for col in pivot_df.columns], ax=ax)

# 配置图表样式
ax.set_xlabel('Date', fontsize=14)
ax.set_ylabel('Count', fontsize=14)
ax.set_title('Count of Viewing Type Over Time', fontsize=20)
ax.legend(title='Device', bbox_to_anchor=(1.05, 1), loc='upper left')
ax.tick_params(axis='x', rotation=45)

4. 添加堆叠区域百分比标注

遍历每个柱子的堆叠部分,计算当前部分占该柱子总计数的百分比,并标注在对应位置:

# 遍历每个日期对应的柱子
for i, date in enumerate(pivot_df.index):
    total = pivot_df.loc[date].sum()
    current_height = 0
    # 遍历每个设备的计数
    for device in pivot_df.columns:
        count = pivot_df.loc[date, device]
        if count == 0:
            continue
        # 计算百分比
        percentage = f'{(count/total)*100:.1f}%'
        # 标注位置:x为柱子中心,y为当前堆叠高度的中间位置
        ax.text(i, current_height + count/2, percentage, ha='center', va='center', fontsize=10)
        current_height += count

完整代码

import pandas as pd
import matplotlib.pyplot as plt

# 原始数据
df = pd.DataFrame(data = {'id' : ['hbo', 'hbo', 'hbo', 'fox','fox','fox', 'NBC', 'NBC', 'NBC'], 
                     'device': ['laptop', 'tv', 'cellphone','laptop', 'tv', 'cellphone','laptop', 'tv', 'cellphone'], 
                     'count': [100,200,300, 400, 300, 200, 900, 1000, 100], 
                    'date': ['2022-04-30', '2022-05-30','2022-06-30', '2022-07-30', '2022-08-30','2022-09-30', 
                            '2022-10-30', '2022-11-30','2022-12-30']})

# 数据透视转换
pivot_df = df.pivot(index='date', columns='device', values='count')

# 自定义颜色映射
color_map = {'tv': 'red', 'laptop': 'steelblue', 'cellphone': 'limegreen'}

# 绘制堆叠柱状图
fig, ax = plt.subplots(figsize=(10, 6))
pivot_df.plot(kind='bar', stacked=True, color=[color_map[col] for col in pivot_df.columns], ax=ax)

# 配置图表样式
ax.set_xlabel('Date', fontsize=14)
ax.set_ylabel('Count', fontsize=14)
ax.set_title('Count of Viewing Type Over Time', fontsize=20)
ax.legend(title='Device', bbox_to_anchor=(1.05, 1), loc='upper left')
ax.tick_params(axis='x', rotation=45)

# 添加百分比标注
for i, date in enumerate(pivot_df.index):
    total = pivot_df.loc[date].sum()
    current_height = 0
    for device in pivot_df.columns:
        count = pivot_df.loc[date, device]
        if count == 0:
            continue
        percentage = f'{(count/total)*100:.1f}%'
        ax.text(i, current_height + count/2, percentage, ha='center', va='center', fontsize=10)
        current_height += count

plt.tight_layout()
plt.show()

内容的提问来源于stack exchange,提问作者Beans On Toast

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 20:41:23