使用matplotlib.image.imsave与matplotlib.pyplot.savefig保存TIFF栅格文件时输出尺寸差异问题
为什么plt.savefig会缩小图像尺寸?怎么修改?
这个问题的核心是matplotlib两种保存方式的本质差异:
matplotlib.image.imsave是直接把numpy数组的像素数据写入文件,完全保留你原数组的(10980x10980)尺寸,所以文件体积大(毕竟10k×10k的8位RGBA图像,算下来就是10980×10980×4字节≈480MB,和你看到的一致)。- 而
plt.imshow+plt.savefig的流程是:先创建一个默认尺寸的画布(默认是6.4英寸宽×4.8英寸高,默认dpi=100,所以6.4×100=640像素,4.8×100=480像素),然后把你的大数组缩放到这个小画布上渲染显示,最后保存的是这个渲染后的画布内容——这就是为什么尺寸变成了640x480,文件也小很多。
解决方法:让savefig保存原尺寸图像
场景1:需要保留colorbar
要让plt.savefig输出和原数组尺寸一致的图像,你需要手动设置画布的尺寸和dpi,让画布的像素尺寸完全匹配原数组。计算逻辑很简单:
画布尺寸(英寸)= 数组像素尺寸 / dpi
比如原数组是10980x10980,用默认dpi=100的话,画布宽高就是10980/100=109.8英寸。对应的代码如下:
import matplotlib.pyplot as plt import numpy as np # 你的10980x10980数组 data = np.random.rand(10980, 10980) # 设定dpi(和保存时保持一致) dpi = 100 # 根据数组像素尺寸计算画布大小(英寸) fig_width = data.shape[1] / dpi fig_height = data.shape[0] / dpi # 创建匹配尺寸的画布 fig, ax = plt.subplots(figsize=(fig_width, fig_height), dpi=dpi) # 绘制图像 im = ax.imshow(data) # 添加colorbar,确保布局正常 fig.colorbar(im, ax=ax) # 保存时指定dpi,并用bbox_inches='tight'去掉多余空白 plt.savefig('file_with_colorbar.tiff', dpi=dpi, bbox_inches='tight') plt.close()
这样保存的TIFF就会是10980x10980的尺寸,文件大小也会和imsave的版本接近(因为多了colorbar,可能略大一点)。
场景2:不需要colorbar
如果不需要colorbar,直接用plt.imsave更简单,它会直接保存原数组的尺寸:
plt.imsave('file_no_colorbar.tiff', data, cmap='viridis')
额外提醒
- 一定要保证
subplots设置的dpi和savefig的dpi一致,否则最终像素尺寸会出现偏差。 bbox_inches='tight'参数很关键,它会自动调整画布大小以包含所有元素(比如colorbar),避免内容被裁剪或者保留多余空白。
内容的提问来源于stack exchange,提问作者Raghav Arora




