使用Pandas绘制堆叠柱状图:按名称分组、年份分层并标注数据包数
实现带数值标注的堆叠柱状图
先明确你的需求:基于给定的长格式DataFrame,绘制以name为X轴、year作为堆叠分层、每个堆叠块标注对应total packets数值的堆叠柱状图。你之前的代码思路偏了——你是按列统计类别出现的次数,但我们需要的是把数据转换成宽表后做堆叠可视化,还要添加数值标注。
正确实现步骤
1. 数据预处理:将长表转为宽表
首先要把原始的长格式DataFrame转换成宽格式,让每个name作为行索引,每个year作为列,对应的值为total packets,缺失的年份用0填充(避免出现空堆叠块):
import pandas as pd import matplotlib.pyplot as plt # 构造原始DataFrame data = { 'name': ['pak', 'pak', 'pak', 'ind', 'ind', 'afg', 'afg', 'afg'], 'year': [2016, 2018, 2022, 2019, 2021, 2017, 2018, 2022], 'total packets': [4, 18, 5, 10, 9, 2, 32, 31] } old_df = pd.DataFrame(data) # 透视转换:name为行,year为列,值为total packets,缺失值填充0 pivot_df = old_df.pivot(index='name', columns='year', values='total packets').fillna(0)
2. 绘制基础堆叠柱状图
用透视后的宽表直接绘制堆叠柱状图:
ax = pivot_df.plot(kind='bar', stacked=True, figsize=(10, 6)) plt.title('Total Packets by Country and Year') plt.xlabel('Country Name') plt.ylabel('Total Packets') plt.legend(title='Year')
3. 给每个堆叠块添加数值标注
遍历图表中的每个堆叠片段,计算中心位置并标注对应的total packets数值:
# 遍历所有堆叠块 for p in ax.patches: width, height = p.get_width(), p.get_height() if height > 0: # 跳过数值为0的空堆叠块 x_pos, y_pos = p.get_xy() # 在块中心位置添加文本 ax.text(x_pos + width/2, y_pos + height/2, f'{int(height)}', # 转为整数显示更清晰 ha='center', va='center') plt.show()
为什么你的原始代码没达到预期?
你之前的代码是对每一列分组统计类别出现的次数,本质是计算各列的类别频率,和我们需要的展示不同年份的total packets堆叠数值逻辑完全不符。比如你对name分组统计的是每个国家在原始数据中出现的次数,而不是对应的total packets数值,自然出不来想要的效果。
内容的提问来源于stack exchange,提问作者Jlow
相关产品推荐
相关产品推荐

