基于多层索引DataFrame绘制堆叠与多组柱状图求助
实现双层堆叠式多组柱状图方案
你的DataFrame以年份(2005、2006)为行索引,列对应不同房型(1-RM、2-RM、3-RM、4-RM、5-RM、EXEC),每个单元格存储区域与数值的映射字典。要绘制目标双层堆叠柱状图,需先完成数据格式转换,再用matplotlib实现绘图。
步骤1:数据预处理
将嵌套的字典结构展开为包含年份、房型、区域、数值的长格式DataFrame,方便后续绘图:
import pandas as pd # 假设原始DataFrame名为df,先重置索引把年份转为列 df_reset = df.reset_index().rename(columns={'index': 'Year'}) # 遍历每行数据,展开字典 processed_data = [] for _, row in df_reset.iterrows(): current_year = row['Year'] # 遍历所有房型列 for room_category in ['1-RM', '2-RM', '3-RM', '4-RM', '5-RM', 'EXEC']: area_value_dict = row[room_category] # 遍历字典中的区域和数值 for area, value in area_value_dict.items(): # 可选:过滤零值,减少无效数据;若需保留则删除此判断 if value > 0: processed_data.append({ 'Year': current_year, 'Room_Type': room_category, 'Area': area, 'Value': value }) # 转换为可直接用于绘图的DataFrame plot_ready_df = pd.DataFrame(processed_data)
步骤2:绘制双层堆叠柱状图
以下代码实现按年份分组,每组内按房型堆叠,每个房型堆叠内再按区域细分的双层堆叠效果:
import matplotlib.pyplot as plt import numpy as np # 获取唯一的年份、房型、区域列表 unique_years = plot_ready_df['Year'].unique() unique_rooms = plot_ready_df['Room_Type'].unique() unique_areas = plot_ready_df['Area'].unique() # 设置柱子宽度与X轴刻度位置 bar_width = 0.2 x_axis = np.arange(len(unique_years)) # 创建画布 fig, ax = plt.subplots(figsize=(14, 9)) # 外层循环:遍历房型,在每个年份分组内绘制房型对应的堆叠柱 for room_idx, room_type in enumerate(unique_rooms): # 筛选当前房型的数据 room_subset = plot_ready_df[plot_ready_df['Room_Type'] == room_type] # 按年份和区域聚合,补全缺失值为0 pivot_data = room_subset.pivot(index='Year', columns='Area', values='Value').fillna(0) # 内层堆叠的底部初始值 stack_bottom = np.zeros(len(unique_years)) # 内层循环:遍历区域,绘制每个区域的堆叠片段 for area in unique_areas: area_values = pivot_data[area].values ax.bar( x_axis + room_idx * bar_width, area_values, bar_width, bottom=stack_bottom, label=f"{room_type} - {area}" ) stack_bottom += area_values # 设置轴标签与刻度 ax.set_xlabel('年份', fontsize=12) ax.set_xticks(x_axis + bar_width * (len(unique_rooms)-1)/2) ax.set_xticklabels(unique_years, fontsize=11) ax.set_ylabel('数值', fontsize=12) ax.set_title('双层堆叠式多组柱状图', fontsize=14, pad=20) # 添加图例(放置在画布外侧避免遮挡) ax.legend(bbox_to_anchor=(1.02, 1), loc='upper left', fontsize=9) # 自动调整布局 plt.tight_layout() plt.show()
自定义调整说明
- 若需更改堆叠层级(比如外层按区域、内层按房型),只需调整循环的遍历顺序和数据筛选逻辑。
- 若不需要过滤零值,删除预处理阶段的
if value > 0判断即可。 - 可通过修改
bar_width、figsize参数调整柱子宽度和画布大小,适配不同展示需求。
内容的提问来源于stack exchange,提问作者Nirvana
相关产品推荐
相关产品推荐

