如何为Matplotlib双向条形图添加特定标签与分组间距
实现目标样式的双向条形图调整方案
现有成果与数据
已生成的双向条形图
当前生成的双向条形图为左右分栏布局,分别展示Fluids和Vasopressors的横向条形,但无分组变量标签和组间间距。
使用的DataFrame数据
variable level margins_fluid margins_vp 0 volume 1L 0.718 0.690 1 volume 2L 0.501 0.808 2 volume 5L 0.181 0.920 3 MAP 64 0.434 0.647 4 MAP 58 0.477 0.854 5 MAP 52 0.489 0.904 6 Exam dry 0.668 0.713 7 exam euvolemic 0.475 0.798 8 exam wet 0.262 0.893 9 history COPD 0.506 0.804 10 history Kidney 0.441 0.778 11 history HF 0.450 0.832 12 Case 1 (PIV) 0.435 0.802 13 Case 2 (CVC) 0.497 0.809
当前使用的代码
font_color = '#525252' hfont = {'fontname':'Calibri'} facecolor = '#eaeaf2' index = fluid_vp_1_2.index column0 = fluid_vp_1_2['margins_fluid'] column1 = fluid_vp_1_2['margins_vp'] title0 = 'Fluids' title1 = 'Vasopressors' fig, axes = plt.subplots(figsize=(10,5), facecolor=facecolor, ncols=2, sharey=True) fig.tight_layout() axes[0].barh(index, column0, align='center', color='dimgray', zorder=10) axes[0].set_title(title0, fontsize=18, pad=15, color='black', **hfont) axes[1].barh(index, column1, align='center', color='lightgray', zorder=10) axes[1].set_title(title1, fontsize=18, pad=15, color='black', **hfont) # 反转左侧x轴 axes[0].invert_xaxis() # 反转y轴,让数据从高到低展示 plt.gca().invert_yaxis() # 隐藏y轴刻度 axes[0].set_yticks([]) axes[1].set_yticks([])
需求说明
需将图表调整为目标样式(最左侧面板):
- 每个变量组(volume、MAP、Exam、history、Case)仅显示一次变量名
- 各变量组之间增加明显间距(Case组含2个层级,其余组含3个层级)
实现步骤与代码修改建议
1. 预处理数据:统一变量名并计算y轴位置
先修正数据中变量名的大小写不一致问题,再手动计算每个条形的y轴坐标,预留组间间距:
import pandas as pd import matplotlib.pyplot as plt # 统一variable列的大小写,避免分组错误 fluid_vp_1_2['variable'] = fluid_vp_1_2['variable'].str.capitalize() # 定义组间距和组内条形高度 group_gap = 0.8 bar_height = 0.8 # 计算每个条形的y轴位置 y_positions = [] current_y = 0 # 按变量分组遍历 for _, group in fluid_vp_1_2.groupby('variable'): group_size = len(group) # 给组内每个条形分配连续的y坐标 group_ys = list(range(current_y, current_y + group_size)) y_positions.extend(group_ys) # 组之间添加间距 current_y += group_size + group_gap # 将计算好的y坐标加入DataFrame fluid_vp_1_2['y_pos'] = y_positions
2. 绘制条形图并添加分组标签
修改绘图逻辑,使用自定义y坐标绘制条形,同时在每组中心位置添加变量名:
font_color = '#525252' hfont = {'fontname':'Calibri'} facecolor = '#eaeaf2' title0 = 'Fluids' title1 = 'Vasopressors' # 调整画布大小,适配分组标签 fig, axes = plt.subplots(figsize=(10,7), facecolor=facecolor, ncols=2, sharey=True) # 缩小左右面板间距 fig.subplots_adjust(wspace=0.1) # 绘制左侧Fluids条形图 axes[0].barh(fluid_vp_1_2['y_pos'], fluid_vp_1_2['margins_fluid'], align='center', color='dimgray', zorder=10, height=bar_height) axes[0].set_title(title0, fontsize=18, pad=15, color='black', **hfont) axes[0].invert_xaxis() # 绘制右侧Vasopressors条形图 axes[1].barh(fluid_vp_1_2['y_pos'], fluid_vp_1_2['margins_vp'], align='center', color='lightgray', zorder=10, height=bar_height) axes[1].set_title(title1, fontsize=18, pad=15, color='black', **hfont) # 设置y轴刻度为层级标签 axes[0].set_yticks(fluid_vp_1_2['y_pos']) axes[0].set_yticklabels(fluid_vp_1_2['level'], fontsize=12, **hfont) # 在左侧添加分组变量名,居中显示在每组中间 for var_name, group in fluid_vp_1_2.groupby('variable'): # 计算组的中心y坐标 center_y = group['y_pos'].mean() # 在y轴外侧添加加粗的分组名 axes[0].text(-0.1, center_y, var_name, va='center', ha='right', fontsize=14, fontweight='bold', **hfont) # 调整y轴范围,避免顶部/底部条形被截断 axes[0].set_ylim(-0.5, max(y_positions) + 0.5) # 隐藏右侧面板的y轴刻度 axes[1].set_yticks([]) # 优化视觉:移除多余边框,添加x轴网格线 for ax in axes: ax.spines[['top', 'right', 'left']].set_visible(False) ax.grid(axis='x', linestyle='--', alpha=0.7) plt.show()
3. 关键调整说明
- 统一变量名:修正原数据中
Exam和exam的大小写差异,确保分组准确 - 自定义y坐标:通过手动计算实现组间间距,
group_gap参数可根据需求调整间距大小 - 分组标签添加:利用
groupby获取每组中心位置,在y轴外侧添加变量名,实现每组仅显示一次的效果 - 视觉优化:调整子图间距、条形高度、网格样式,贴近目标图表的简洁风格
内容的提问来源于stack exchange,提问作者hulio_entredas
相关产品推荐
相关产品推荐

