如何在Matplotlib中设置figsize与dpi并解决子图间隙及保存格式问题
解决Matplotlib拼接图片的三个核心问题
问题1:保存图片尺寸不符合预期
原因在于两点:一是用整数除法//计算figsize导致精度丢失,二是bbox_inches='tight'会自动裁剪布局,改变最终尺寸。
解决方法:
- 用浮点数计算figsize:
figsize=(cols * img_size[0]/dpi, rows * img_size[1]/dpi),确保dpi * figsize的结果正好等于目标像素数(2304×1792) - 移除
bbox_inches='tight'参数,避免自动裁剪;如果需要保留轴标签,需手动调整边距预留空间
问题2:子图间存在间隙
即使设置wspace=0和hspace=0,Matplotlib的默认布局仍可能因子图aspect或边距设置产生间隙。
解决方法:
- 显式设置子图
aspect='equal'(imshow默认值,但显式设置更稳妥) - 用
plt.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=0, hspace=0)彻底消除边距和子图间距 - 若添加轴标签导致布局偏移,调整
left参数预留空间(比如left=0.1),同时重新计算figsize保证图片主体尺寸不变
问题3:LaTeX适配的高画质保存格式
- 矢量图格式:优先选
PDF,LaTeX原生支持,缩放不失真,适合包含文字或线条的内容;即使嵌入位图,画质也不受影响 - 位图格式:选
PNG并设置高dpi(比如300),或TIFF,两者都能提供高分辨率,适合纯位图场景 - 避免使用JPG,压缩会损失画质,不适合学术文档
修改后的完整代码
from PIL import Image import numpy as np import matplotlib.pyplot as plt cols = 9 rows = 7 img_size = (256, 256) dpi = 100 # 精确计算figsize,确保dpi*figsize=目标像素数 fig_width = cols * img_size[0] / dpi fig_height = rows * img_size[1] / dpi # 预留左侧边距放ylabel,可根据字体大小调整 fig_width += 0.8 fig, axes = plt.subplots(rows, cols, figsize=(fig_width, fig_height), dpi=dpi) for row_idx, row in enumerate(axes): images = [Image.new('RGB', img_size, color='grey') for _ in range(cols)] for col_idx, (ax, img) in enumerate(zip(row, images)): ax.imshow(img, aspect='equal') # 隐藏所有边框和刻度 for spine in ax.spines.values(): spine.set_visible(False) ax.set_xticks([]) ax.set_yticks([]) if col_idx == 0: # 设置ylabel并调整间距避免偏移 ax.set_ylabel('name', fontsize=30, labelpad=20) # 消除所有间距和边距,左侧预留空间放标签 plt.subplots_adjust(left=0.1, bottom=0, right=1, top=1, wspace=0, hspace=0) # 保存为PDF适合LaTeX,或用png并设高dpi plt.savefig('example.pdf', format='pdf') # plt.savefig('example.png', dpi=300, format='png') plt.close()
内容的提问来源于stack exchange,提问作者nietoperz21
相关产品推荐
相关产品推荐

