如何在多幅matplotlib水平柱状图中固定ylabel间距并对齐y轴
解决Matplotlib水平柱状图左脊柱对齐问题
当不同水平柱状图的Y轴标签宽度差异较大时,要让所有图表的左脊柱(黑色竖线)对齐,核心是给所有图表设置统一的左侧留白空间,以下是两种实用实现方法:
方法一:固定左侧边距
直接通过subplots_adjust设置固定比例的左侧留白,不管标签长度如何,左脊柱位置都保持一致。只需根据最长标签的长度调整left参数值,确保标签不被截断。
示例代码:
import matplotlib.pyplot as plt def generate_barh(labels, values, left_margin=0.3): # 创建图表,高度适配标签数量 fig, ax = plt.subplots(figsize=(8, 0.07 + 0.25 * len(values))) # 固定左侧留白比例(范围0-1,对应图表总宽度的占比) plt.subplots_adjust(left=left_margin) # 绘制水平柱状图 ax.barh(labels, values, color='#1f77b4') return fig, ax # 测试不同标签长度的图表 labels_group1 = ['AAA', 'BBBBBBBBBBBBB', 'CCCCCC', 'DDDDDDDDDD'] values_group1 = [0, 2, 2, 5] fig1, ax1 = generate_barh(labels_group1, values_group1) labels_group2 = ['Short', 'Medium Label', 'Super Long Label That Takes More Space'] values_group2 = [3, 1, 4] fig2, ax2 = generate_barh(labels_group2, values_group2) plt.show()
方法二:自动计算统一边距(适配所有图表)
如果有多个图表,可先计算所有标签中最宽的宽度,再据此生成统一的左侧边距,既保证标签不截断,又不会浪费多余空间。
示例代码:
import matplotlib.pyplot as plt import matplotlib as mpl def calc_max_label_width(all_label_groups): # 创建临时轴计算文本宽度,避免影响主图表 temp_fig, temp_ax = plt.subplots(figsize=(1,1)) max_width = 0 # 遍历所有标签组,找出最宽的标签 for labels in all_label_groups: for label in labels: # 获取标签文本的实际宽度(转换为英寸) text_bbox = temp_ax.text(0, 0, label, fontsize=mpl.rcParams['axes.labelsize']).get_window_extent() label_width = text_bbox.transformed(temp_fig.dpi_scale_trans.inverted()).width if label_width > max_width: max_width = label_width plt.close(temp_fig) return max_width # 所有图表的标签集合 all_labels = [ ['AAA', 'BBBBBBBBBBBBB', 'CCCCCC', 'DDDDDDDDDD'], ['Short', 'Medium Label', 'Super Long Label That Takes More Space'] ] # 计算最长标签的宽度,再换算为左侧边距比例(图表宽度为8英寸) max_label_width = calc_max_label_width(all_labels) unified_left_margin = (max_label_width / 8) + 0.05 # +0.05是预留的小余量 # 生成对齐的图表 def generate_barh_unified(labels, values, left_margin): fig, ax = plt.subplots(figsize=(8, 0.07 + 0.25 * len(values))) plt.subplots_adjust(left=left_margin) ax.barh(labels, values, color='#ff7f0e') return fig, ax fig1, ax1 = generate_barh_unified(all_labels[0], [0,2,2,5], unified_left_margin) fig2, ax2 = generate_barh_unified(all_labels[1], [3,1,4], unified_left_margin) plt.show()
补充技巧
也可以直接通过ax.set_position()精确控制轴的位置,所有图表使用相同参数即可实现对齐:
# 参数格式:[左侧起始位置, 底部起始位置, 轴宽度, 轴高度] ax.set_position([0.3, 0.1, 0.65, 0.8])
内容的提问来源于stack exchange,提问作者Minty
相关产品推荐
相关产品推荐

