如何实现月度分组下年度子组的PC值堆叠Stacked Bar Plot?
解决方案
需求可行性:完全可行
只要调整分组数据的处理逻辑和绘图细节,就能实现每个月份分组下的年度条形内部堆叠PC值,同时保持原有条形的数量与位置不变。
具体实现步骤(以Matplotlib为例)
假设你的数据包含month(月份)、year(年度)、pc_category(PC类别)、value(数值)核心字段:
数据预处理
- 先按
month和year做双层分组,确保每个月份下的年度分组完整;再在每个年度分组内拆分出各PC类别的数据。 - 计算年度条形的位置偏移:因为每个月份要放置多个年度条形,需给每个年度分配一个偏移量(比如条形宽度设为0.2,4个年度的偏移为
-0.3, -0.1, 0.1, 0.3,以月份刻度为中心)。
- 先按
循环绘制堆叠条形
- 遍历每个月份,再遍历该月份下的每个年度:
- 提取当前年度下各PC类别的汇总数值,按顺序堆叠。
- 用
bottom参数控制堆叠起始高度,初始值为0,每绘制一个PC类别就更新bottom为当前堆叠的总高度。 - 调用你的颜色字典为每个PC类别匹配对应颜色。
- 核心代码片段:
import matplotlib.pyplot as plt import pandas as pd # 假设数据已加载为df,包含month, year, pc_category, value字段 color_dict = {"PC1": "#FF5733", "PC2": "#33FF57", "PC3": "#3357FF"} # 自定义颜色字典 months = range(1, 13) years = df['year'].unique() bar_width = 0.2 # 计算每个年度条形相对于月份刻度的偏移量 offsets = [bar_width * i - bar_width * (len(years)-1)/2 for i in range(len(years))] fig, ax = plt.subplots(figsize=(12, 6)) for month_idx, month in enumerate(months): month_data = df[df['month'] == month] for year_idx, year in enumerate(years): year_data = month_data[month_data['year'] == year] # 按PC类别汇总数值 pc_grouped = year_data.groupby('pc_category')['value'].sum() bottom = 0 for pc, val in pc_grouped.items(): ax.bar( month_idx + offsets[year_idx], val, bar_width, bottom=bottom, color=color_dict[pc] ) bottom += val # 设置x轴刻度与标签,避免错位 ax.set_xticks(range(len(months))) ax.set_xticklabels([f"Month {m}" for m in months]) # 添加图例等元素 plt.legend(color_dict.keys(), title="PC Category") plt.xlabel("Month") plt.ylabel("Value") plt.show()
- 遍历每个月份,再遍历该月份下的每个年度:
规避x轴标签错位
- 手动设置
xticks在每个月份的中心位置(即range(len(months))),年度条形通过偏移量分布在中心两侧,彻底解决自动布局导致的标签错位问题。
- 手动设置
替代可视化方案(若堆叠条形仍有适配问题)
如果上述方法仍无法满足需求,可尝试以下方案:
- 分组堆叠热力图:x轴为月份,y轴为年度,每个单元格内用堆叠色块展示PC值占比,搭配颜色深浅表示数值大小,适合对比不同年度-月份的PC分布差异。
- 多子图折线图:为每个PC类别单独创建子图,x轴为月份,不同年度用不同颜色折线表示数值变化,清晰呈现单个PC的月度-年度趋势。
- 百分比堆叠条形图(带绝对值标注):将每个年度条形的总高度设为100%,堆叠展示各PC的占比,同时在条形旁标注绝对值,兼顾占比分析与数量展示。
内容的提问来源于stack exchange,提问作者Warehouse_Worker
相关产品推荐
相关产品推荐

