如何为Pandas+Matplotlib绘制的分组柱状图添加次级嵌套分组
嵌套分组柱状图实现方案
要实现按Person、测试组、子测试的三级嵌套分组柱状图,需要先将宽表转为长表拆分分组维度,再手动计算每个柱子的x轴位置绘制,完整实现代码如下:
import pandas as pd import matplotlib.pyplot as plt # 原始数据 df=pd.DataFrame({ 'run-1a':[0.3, 0.3, 0.4, 0.4], 'run-1b':[0.3, 0.3, 0.4, 0.5], 'run-2a':[0.7, 0.9, 0.8, 0.9], 'run-2b':[0.2, 0.3, 0.5, 0.5], 'Person':["person1","person2","person3","person4"] }) # 1. 数据预处理:拆分两级分组维度 df_melt = df.melt(id_vars='Person', var_name='run_id', value_name='score') # 拆分主分组(run-1/run-2)和子分组(a/b) df_melt['main_group'] = df_melt['run_id'].str.slice(0, -1) df_melt['sub_group'] = df_melt['run_id'].str.slice(-1) # 2. 配置绘图参数 bar_width = 0.18 # 单个柱子宽度 sub_gap = 0.02 # 同主分组下子柱子间距 main_gap = 0.3 # 同一个Person下两个主分组的间距 person_gap = 1.2 # 不同Person之间的间距 color_map = {'run-1a':'b', 'run-1b':'lightskyblue', 'run-2a':'g', 'run-2b':'lightgreen'} persons = df['Person'].unique() main_groups = ['run-1', 'run-2'] sub_groups = ['a', 'b'] # 计算每个Person的基准x坐标 person_base_x = {p:i * (2*(bar_width+sub_gap) + main_gap + person_gap) for i,p in enumerate(persons)} fig, ax = plt.subplots(figsize=(10,5)) # 3. 循环绘制每个柱子 bars = [] labels = [] for person in persons: base_x = person_base_x[person] for main_idx, main_g in enumerate(main_groups): # 计算当前主分组的基准偏移 main_offset = main_idx * (2*(bar_width+sub_gap) + main_gap) for sub_idx, sub_g in enumerate(sub_groups): run_id = f"{main_g}{sub_g}" # 计算当前柱子的x坐标 x = base_x + main_offset + sub_idx*(bar_width + sub_gap) # 取对应数值 val = df_melt[(df_melt['Person']==person) & (df_melt['run_id']==run_id)]['score'].values[0] # 画柱子 bar = ax.bar(x, val, width=bar_width, color=color_map[run_id]) # 仅第一次添加对应图例 if run_id not in labels: bars.append(bar) labels.append(run_id) # 4. 调整轴和图例 ax.set_xticks([person_base_x[p] + (2*(bar_width+sub_gap) + main_gap)/2 for p in persons]) ax.set_xticklabels(persons, rotation='horizontal') ax.legend(bars, labels, loc='center left', bbox_to_anchor=(1, 0.5)) plt.tight_layout() plt.show()
运行上述代码即可实现你需要的嵌套分组效果:每个Person对应两个大组,分别是run-1组(含run-1a、run-1b两个蓝色系柱子)和run-2组(含run-2a、run-2b两个绿色系柱子),组间有明显间距区分层级。
内容的提问来源于stack exchange,提问作者HungryMolecule
相关产品推荐
相关产品推荐

