如何调整Matplotlib GridSpec子图间距以实现更优对齐?
调整Matplotlib GridSpec布局间距的解决方案
我用matplotlib.gridspec创建了包含3个坐标轴的网格布局,当前代码如下:
from matplotlib import pyplot as plt from matplotlib.gridspec import GridSpec import pandas as pd import numpy as np # 补充原代码缺失的numpy导入 df = pd.DataFrame({'d1': [20,30,40], 'd2': [10,20,30]}, index=['a', 'b', 'c']) # 模拟真实数据结构的数据集 df = df.apply(lambda l: l / l.sum() * 100).T df.index = ['Some dataset', 'Some dataset 2'] fig = plt.figure(figsize=(6.25, 4.0)) gs = GridSpec(3, 2, figure=fig) ax1 = fig.add_subplot(gs[:2, 0]) ax2 = fig.add_subplot(gs[:2, 1]) hbar_ax = fig.add_subplot(gs[2, :]) df.plot(ax=hbar_ax, kind='barh', stacked=True, width=0.5, color=['#FF3B3B', '#F4B083', '#9CD5A4'], legend=None) hbar_ax.invert_yaxis() hbar_ax.set_xlim(-1, 101) for n in df: for i, (cs, ab, pc) in enumerate(zip(df.iloc[:, 0:].cumsum(1)[n], df[n], df[n])): hbar_ax.text(cs - ab / 2, i, str(np.round(pc, 1)) + '%', va = 'center', ha = 'center', fontsize='medium') hbar_ax.tick_params(axis='both', which='both', length=0) hbar_ax.tick_params( axis='x', which='both', bottom=False, top=False, labelbottom=False) plt.tight_layout()
当前生成的图表中,顶部左右两个子图与下方水平条形图的间距过大,且顶部子图的高度比例不够协调。想要调整成顶部子图紧密排列、与下方条形图间距缩小、整体布局更紧凑的效果。
解决方法
通过修改GridSpec的核心参数来精准控制布局比例和间距:
- 设置行高比例:用
height_ratios定义各行高度占比,让顶部两行(对应左右子图)占据更多空间,下方行(条形图)占比更合理 - 缩小行间距:用
hspace参数减小行与行之间的空隙,拉近顶部子图和下方条形图的距离 - 微调整体边距:配合
tight_layout的pad参数控制图表整体的内边距
修改后的完整代码
from matplotlib import pyplot as plt from matplotlib.gridspec import GridSpec import pandas as pd import numpy as np df = pd.DataFrame({'d1': [20,30,40], 'd2': [10,20,30]}, index=['a', 'b', 'c']) df = df.apply(lambda l: l / l.sum() * 100).T df.index = ['Some dataset', 'Some dataset 2'] fig = plt.figure(figsize=(6.25, 4.0)) # 新增height_ratios控制行高占比,hspace缩小行间距 gs = GridSpec(3, 2, figure=fig, height_ratios=[4, 4, 2], hspace=0.15) ax1 = fig.add_subplot(gs[:2, 0]) ax2 = fig.add_subplot(gs[:2, 1]) hbar_ax = fig.add_subplot(gs[2, :]) df.plot(ax=hbar_ax, kind='barh', stacked=True, width=0.5, color=['#FF3B3B', '#F4B083', '#9CD5A4'], legend=None) hbar_ax.invert_yaxis() hbar_ax.set_xlim(-1, 101) for n in df: for i, (cs, ab, pc) in enumerate(zip(df.iloc[:, 0:].cumsum(1)[n], df[n], df[n])): hbar_ax.text(cs - ab / 2, i, str(np.round(pc, 1)) + '%', va = 'center', ha = 'center', fontsize='medium') hbar_ax.tick_params(axis='both', which='both', length=0) hbar_ax.tick_params( axis='x', which='both', bottom=False, top=False, labelbottom=False) # 调整整体内边距,让布局更紧凑 plt.tight_layout(pad=0.2) plt.show()
修改后,顶部子图的高度比例更贴合目标效果,同时缩小了与下方条形图的间距,整体布局更紧凑协调。
内容的提问来源于stack exchange,提问作者Loxx
相关产品推荐
相关产品推荐

