Matplotlib:调整子图网格特定子图间距,实现共享Y轴标签居中
解决Matplotlib多子图网格中特定子图间距与共享Y轴标签居中问题
我有一个2×4的Matplotlib子图网格,需要仅调整第二行中两个子图(ax5、ax6)之间的空白间距,让它们的共享Y轴标签居中且不与任一图表重叠。现有的双生子图解决方案会影响全局子图间距,无法适配多子图场景。
修改后的实现代码
import matplotlib.pyplot as plt import numpy as np from matplotlib import transforms fig = plt.figure(figsize=(15, 10)) # 主网格:2行4列 gs_main = fig.add_gridspec(2, 4) # 第一行子图 ax1 = fig.add_subplot(gs_main[0, 0]) ax2 = fig.add_subplot(gs_main[0, 1:3]) ax3 = fig.add_subplot(gs_main[0, 3]) # 第二行子图:为第2、3列创建独立子网格,单独控制ax5和ax6的间距 gs_sub = gs_main[1, 1:3].subgridspec(1, 2, wspace=0.8) ax4 = fig.add_subplot(gs_main[1, 0]) ax5 = fig.add_subplot(gs_sub[0, 0]) ax6 = fig.add_subplot(gs_sub[0, 1]) ax7 = fig.add_subplot(gs_main[1, 3]) np.random.seed(19680801) # 示例数据 people = ('Really Really Long Name', 'Another Long Name', 'Short Name', 'Name', 'N') y_pos = np.arange(len(people)) performance = 3 + 10 * np.random.rand(len(people)) # 绘制ax5 ax5.barh(y_pos, performance, align='center') ax5.set_yticks(y_pos, labels=people) ax5.invert_xaxis() ax5.set_xlabel('Label') ax5.set_title('Bar 1') # 绘制ax6,共享ax5的Y轴并隐藏自身Y轴标签 ax6.barh(y_pos, performance, align='center') ax6.sharey(ax5) ax6.set_yticklabels([]) ax6.set_xlabel('Label') ax6.set_title('Bar 2') # 将ax5的Y轴标签偏移到两个子图中间 dx = 0.5 * (ax6.get_position().x0 - ax5.get_position().x1) / ax5.get_position().width offset = transforms.ScaledTranslation(dx, 0, ax5.transAxes) for label in ax5.yaxis.get_majorticklabels(): label.set_transform(label.get_transform() + offset) label.set_ha('center') fig.tight_layout() plt.show()
关键实现说明
- 嵌套GridSpec:通过
subgridspec为目标子图创建独立子网格,设置的wspace仅作用于ax5和ax6,不会干扰其他子图的布局。 - 共享Y轴优化:让ax6共享ax5的Y轴并隐藏自身Y轴标签,避免重复显示,同时保证Y轴刻度一致。
- 精准标签偏移:使用子图自身的
transAxes坐标系变换替代全局画布变换,将ax5的Y轴标签偏移到两个子图的中间位置,确保标签居中且不与图表重叠。
内容的提问来源于stack exchange,提问作者bjwphneb
相关产品推荐
相关产品推荐

