如何让Matplotlib多图保持一致的Axes/Spine边框尺寸
解决Matplotlib中多图表Axes/Spine边框尺寸一致的问题
问题背景
在Matplotlib中生成多幅图表时,轴刻度数字位数不同会导致Axes(绘图区域)的边框尺寸不一致——刻度位数少的图表,边框(Spine)占据的空间更大;位数多的则更小。调整figsize或宽高比无法解决,需要固定轴在图表中的位置,为多位数刻度预留足够边距。
原示例代码
import matplotlib.pyplot as plt from matplotlib.ticker import FormatStrFormatter import matplotlib.ticker as ticker plt.style.use('classic') plt.rcParams.update({'mathtext.default': 'regular'}) plt.rcParams['font.family'] = 'Arial' plt.rcParams["axes.linewidth"] = 0.50 i=0 plots=['plot1','plot2'] xlabel=['x_plot1','x_plot2'] ylabel=['y_plot1','y_plot2'] for i in range(len(plots)): fig, ax = plt.subplots( figsize=[6.0, 4.8]) fig.tight_layout() if(i==0): ax.plot([0,9], [0,9]) ax.axis([0, 9, 0, 9]) if(i==1): ax.plot([0,1000], [0,1000]) ax.axis([0, 1000, 0, 1000]) ax.set_xlabel(xlabel[i],fontsize='12') ax.set_ylabel(ylabel[i],fontsize='12') ax.grid(linestyle='solid', linewidth=0.6, color='#000000', which='major', zorder=1, clip_on=False) plt.gcf().canvas.draw() ax.set_axisbelow(True) ax.spines['bottom'].set_linewidth(1.5) ax.spines['left'].set_linewidth(1.5) plt.yticks(fontsize='12', zorder=0) plt.xticks(fontsize='12', zorder=0) plt.savefig(plots[i]+'.png', dpi=300, bbox_inches='tight', transparent=False) plt.clf()
解决方案
核心思路是固定图表的边距参数,强制Axes区域在所有图表中保持相同尺寸,不受刻度位数影响。具体修改如下:
- 移除自动调整布局的
fig.tight_layout(),改用手动设置固定边距。 - 使用
plt.subplots_adjust()设置统一的left、right、bottom、top参数,为刻度和标签预留足够空间。
修改后的代码
import matplotlib.pyplot as plt from matplotlib.ticker import FormatStrFormatter import matplotlib.ticker as ticker plt.style.use('classic') plt.rcParams.update({'mathtext.default': 'regular'}) plt.rcParams['font.family'] = 'Arial' plt.rcParams["axes.linewidth"] = 0.50 plots=['plot1','plot2'] xlabel=['x_plot1','x_plot2'] ylabel=['y_plot1','y_plot2'] # 定义统一的边距参数,根据实际需求调整 MARGIN_LEFT = 0.18 MARGIN_RIGHT = 0.95 MARGIN_BOTTOM = 0.18 MARGIN_TOP = 0.95 for i in range(len(plots)): fig, ax = plt.subplots(figsize=[6.0, 4.8]) if(i==0): ax.plot([0,9], [0,9]) ax.axis([0, 9, 0, 9]) if(i==1): ax.plot([0,1000], [0,1000]) ax.axis([0, 1000, 0, 1000]) ax.set_xlabel(xlabel[i],fontsize='12') ax.set_ylabel(ylabel[i],fontsize='12') ax.grid(linestyle='solid', linewidth=0.6, color='#000000', which='major', zorder=1, clip_on=False) plt.gcf().canvas.draw() ax.set_axisbelow(True) ax.spines['bottom'].set_linewidth(1.5) ax.spines['left'].set_linewidth(1.5) plt.yticks(fontsize='12', zorder=0) plt.xticks(fontsize='12', zorder=0) # 设置固定边距,强制Axes区域一致 plt.subplots_adjust(left=MARGIN_LEFT, right=MARGIN_RIGHT, bottom=MARGIN_BOTTOM, top=MARGIN_TOP) plt.savefig(plots[i]+'.png', dpi=300, bbox_inches='tight', transparent=False) plt.clf()
关键调整说明
- 手动设置的边距参数(
MARGIN_LEFT等)需根据字体大小、刻度位数调整,确保能容纳最长的刻度文本和轴标签。 - 移除
fig.tight_layout()避免自动调整边距导致Axes位置变化。 - 所有图表使用相同的边距参数,保证Axes/Spine的边框尺寸完全一致。
内容的提问来源于stack exchange,提问作者Radim Habartík
相关产品推荐
相关产品推荐

