Matplotlib绘图如何保留原图分辨率并添加对齐色条
解决方案
要让绘图中的图像区域像素分辨率与原图完全一致,同时保留对齐的色条,核心是精准控制Matplotlib的画布和轴的像素尺寸,避免默认英寸-像素转换的混乱。以下是两种可靠实现方式:
方法一:按像素直接定义画布
通过设置dpi=1,让画布的figsize直接对应输出像素尺寸,精准分配图像和色条的像素占比:
import numpy as np import matplotlib.pyplot as plt from matplotlib.gridspec import GridSpec img_height, img_width = 100, 50 cbar_pixel_width = 20 # 色条的像素宽度,可按需调整 # 画布尺寸(像素)= 图像宽+色条宽 × 图像高,dpi=1使英寸与像素一一对应 fig = plt.figure(figsize=(img_width + cbar_pixel_width, img_height), dpi=1) # 按像素比例分配图像和色条的轴宽度 gs = GridSpec(1, 2, width_ratios=[img_width, cbar_pixel_width]) # 图像轴:尺寸严格匹配原图像素 ax_img = fig.add_subplot(gs[0]) ax_img.set_axis_off() image = ax_img.imshow( np.arange(img_height * img_width).reshape((img_height, img_width)), cmap="hot", interpolation="none" # 禁用插值,保证像素1:1对应 ) # 色条轴:宽度对应设定的像素值 ax_cbar = fig.add_subplot(gs[1]) colorbar = fig.colorbar(image, cax=ax_cbar) colorbar.set_label('label') # 保存时去除多余边距,确保尺寸精准 plt.savefig('output.png', bbox_inches='tight', pad_inches=0) plt.close()
关键说明:
dpi=1:让figsize的数值直接等于输出图像的像素尺寸,例如figsize=(70,100)会生成70×100像素的结果。width_ratios:按像素比例分配两个轴的宽度,确保图像区域刚好是img_width×img_height像素。interpolation="none":避免Matplotlib对图像进行插值处理,保证原图每个像素对应输出中的一个像素。
方法二:通过dpi反向计算画布尺寸
如果需要使用自定义dpi(如100),可通过像素与英寸的转换关系,计算画布和轴的尺寸:
import numpy as np import matplotlib.pyplot as plt img_height, img_width = 100, 50 dpi = 100 # 自定义dpi值 cbar_inch_width = 0.2 # 色条的英寸宽度 # 图像区域的英寸尺寸 = 像素尺寸 / dpi img_inch_w = img_width / dpi img_inch_h = img_height / dpi # 画布总宽度 = 图像英寸宽度 + 色条英寸宽度 fig = plt.figure(figsize=(img_inch_w + cbar_inch_width, img_inch_h), dpi=dpi) # 手动设置图像轴的位置和尺寸,占满左侧对应区域 ax_img = fig.add_axes([0, 0, img_inch_w/(img_inch_w + cbar_inch_width), 1]) ax_img.set_axis_off() image = ax_img.imshow( np.arange(img_height * img_width).reshape((img_height, img_width)), cmap="hot", interpolation="none" ) # 设置色条轴的位置和尺寸,占满右侧对应区域 ax_cbar = fig.add_axes([img_inch_w/(img_inch_w + cbar_inch_width), 0, cbar_inch_width/(img_inch_w + cbar_inch_width), 1]) colorbar = fig.colorbar(image, cax=ax_cbar) colorbar.set_label('label') plt.savefig('output.png', bbox_inches='tight', pad_inches=0) plt.close()
结果验证:
两种方法生成的output.png中,图像区域的像素尺寸严格为100×50,加上色条后整体尺寸符合预期,完全满足需求。
内容的提问来源于stack exchange,提问作者sleepingrabbit
相关产品推荐
相关产品推荐

