如何在Matplotlib中为Pandas多级索引DataFrame设置分组X轴标签?
解决Pandas堆叠柱状图X轴标签拥挤及分组显示问题
你的多级索引DataFrame在绘制堆叠柱状图时,X轴因同时显示两级索引标签导致拥挤。要实现类似Excel的按第一级索引(pes/tes/des)分组的效果,可以通过Matplotlib手动控制X轴元素来实现,步骤如下:
实现步骤与完整代码
import pandas as pd import matplotlib.pyplot as plt # 示例数据集 data_dict = {'BatteryStorage': {('des-PDef3', 'Central Africa'): 0.0, ('des-PDef3', 'Eastern Africa'): 2475.9, ('des-PDef3', 'North Africa'): 98.0, ('des-PDef3', 'Southern Africa'): 124.0, ('des-PDef3', 'West Africa'): 1500.24, ('pes-PDef3', 'Central Africa'): 0.0, ('pes-PDef3', 'Eastern Africa'): 58.03, ('pes-PDef3', 'North Africa'): 98.0, ('pes-PDef3', 'Southern Africa'): 124.0, ('pes-PDef3', 'West Africa'): 0.0, ('tes-PDef3', 'Central Africa'): 0.0, ('tes-PDef3', 'Eastern Africa'): 1175.86, ('tes-PDef3', 'North Africa'): 98.0, ('tes-PDef3', 'Southern Africa'): 124.0, ('tes-PDef3', 'West Africa'): 0.0}, 'Biomass PP': {('des-PDef3', 'Central Africa'): 44.24, ('des-PDef3', 'Eastern Africa'): 1362.4, ('des-PDef3', 'North Africa'): 178.29, ('des-PDef3', 'Southern Africa'): 210.01999999999998, ('des-PDef3', 'West Africa'): 277.4, ('pes-PDef3', 'Central Africa'): 44.24, ('pes-PDef3', 'Eastern Africa'): 985.36, ('pes-PDef3', 'North Africa'): 90.93, ('pes-PDef3', 'Southern Africa'): 144.99, ('pes-PDef3', 'West Africa'): 130.33, ('tes-PDef3', 'Central Africa'): 44.24, ('tes-PDef3', 'Eastern Africa'): 1362.4, ('tes-PDef3', 'North Africa'): 178.29, ('tes-PDef3', 'Southern Africa'): 210.01999999999998, ('tes-PDef3', 'West Africa'): 277.4}} df = pd.DataFrame.from_dict(data_dict) # 获取多级索引信息 level1 = df.index.get_level_values(0).unique() group_size = len(df.index.get_level_values(1).unique()) # 每组5个区域 x = range(len(df)) # 创建画布和轴对象 fig, ax = plt.subplots(figsize=(12, 6)) # 绘制堆叠柱状图 df['BatteryStorage'].plot(kind='bar', stacked=True, ax=ax, label='BatteryStorage', color='#1f77b4') df['Biomass PP'].plot(kind='bar', stacked=True, ax=ax, label='Biomass PP', color='#ff7f0e') # 设置X轴刻度为第二级索引(区域名称) ax.set_xticklabels(df.index.get_level_values(1), rotation=45, ha='right') # 添加分组分隔线 for i in range(group_size, len(df), group_size): ax.axvline(x=i-0.5, color='gray', linestyle='--', alpha=0.7) # 添加第一级分组标签(顶部) for idx, group_name in enumerate(level1): # 计算每组的中心位置 group_center = idx * group_size + (group_size - 1)/2 ax.text(group_center, ax.get_ylim()[1] * 1.02, group_name.split('-')[0], ha='center', fontweight='bold', fontsize=12) # 调整布局,防止标签被截断 plt.tight_layout() plt.legend() plt.show()
关键细节说明
- 提取索引层级:通过
get_level_values分别获取两级索引的唯一值,确定分组大小 - 手动绘制堆叠柱:直接调用各列的plot方法,确保堆叠效果,同时保留对轴对象的控制权
- 添加分隔线:在每组结束位置绘制灰色虚线,清晰区分不同分组
- 顶部分组标签:计算每组中心位置,在图表上方添加第一级索引的简写(去掉-PDef3),避免标签重复
- 刻度调整:将X轴刻度设置为第二级索引(区域),并旋转45度提升可读性
内容的提问来源于stack exchange,提问作者hbstha123
相关产品推荐
相关产品推荐

