Pandas绘制双Y轴分组堆叠柱状图实现方案
双Y轴分组堆叠柱状图实现方案
原有代码无法实现需求的核心原因有两个:
- 直接对groupby结果调用
plot.bar()会为每个MainCategory单独生成独立画布,无法在同一坐标系下实现分组并排效果 - 直接调用
unstack()报错是因为没有先对SubCategory维度做聚合重排,多重索引结构不匹配matplotlib的绘图入参要求
完整实现代码
import pandas as pd import matplotlib.pyplot as plt import numpy as np # 读取CSV数据,跳过前2行注释头 data = pd.read_csv('failureEventStatistic_total_Top10.csv', sep=',', header=2) # 提取所有主分类作为X轴刻度,固定排序 main_categories = sorted(data['MainCategory'].unique()) x_pos = np.arange(len(main_categories)) bar_width = 0.35 # 单组内两根柱子的宽度 # 构造透视表:行为主分类,列为子分类,值分别对应时长、事件数,空值补0 dur_pivot = data.pivot_table( index='MainCategory', columns='SubCategory', values='DurationH', aggfunc='sum' ).fillna(0).reindex(main_categories) num_pivot = data.pivot_table( index='MainCategory', columns='SubCategory', values='Number', aggfunc='sum' ).fillna(0).reindex(main_categories) # 创建画布与双Y轴 fig, ax_left = plt.subplots(figsize=(12, 7)) ax_right = ax_left.twinx() # 绘制左Y轴对应的DurationH堆叠柱,位置在组内左偏移 bottom_dur = np.zeros(len(main_categories)) for sub_cat in dur_pivot.columns: ax_left.bar( x_pos - bar_width/2, dur_pivot[sub_cat], bar_width, bottom=bottom_dur, label=f'时长-{sub_cat}' ) bottom_dur += dur_pivot[sub_cat].values # 绘制右Y轴对应的Number堆叠柱,位置在组内右偏移,加斜纹做视觉区分 bottom_num = np.zeros(len(main_categories)) for sub_cat in num_pivot.columns: ax_right.bar( x_pos + bar_width/2, num_pivot[sub_cat], bar_width, bottom=bottom_num, label=f'次数-{sub_cat}', hatch='//' ) bottom_num += num_pivot[sub_cat].values # 坐标轴配置 ax_left.set_xlabel('主分类') ax_left.set_ylabel('累计时长 [h]', color='#1f77b4') ax_left.tick_params(axis='y', labelcolor='#1f77b4') ax_left.set_xticks(x_pos, main_categories, rotation=45) ax_right.set_ylabel('累计事件次数', color='#ff7f0e') ax_right.tick_params(axis='y', labelcolor='#ff7f0e') # 合并双轴图例,放在画布外侧避免遮挡 handles_l, labels_l = ax_left.get_legend_handles_labels() handles_r, labels_r = ax_right.get_legend_handles_labels() ax_left.legend( handles_l + handles_r, labels_l + labels_r, bbox_to_anchor=(1.18, 1), loc='upper left' ) plt.tight_layout() plt.show()
实现效果说明
- X轴按MainCategory做分组刻度,每个分组下左右并排两根柱子,分别对应时长、事件数两个指标
- 每根柱子内部按SubCategory维度分层堆叠,完全匹配需求
- 双Y轴分别适配两个量纲差异较大的指标,不会出现小数值被压缩看不到的问题
- 事件数系列柱子增加斜纹填充,和时长系列做明确视觉区分,避免同子分类颜色相近造成混淆
内容的提问来源于stack exchange,提问作者WolfiG
相关产品推荐
相关产品推荐

