如何缩放含不同宽高比图像的子图,使子图高度一致?
让Matplotlib左右子图高度一致的解决方案
问题原因
subplots默认会让子图的绘图区域(axes)尺寸一致,但imshow会根据图像的长宽比自动调整显示比例(默认aspect='equal'),导致子图实际显示的图像高度不一样。这是设计行为,因为imshow优先保证图像不被拉伸变形。
解决方法
方法1:统一设置imshow的aspect参数
如果不需要严格保持图像的原始长宽比,可以将aspect设为'auto',让图像自适应子图尺寸:
import matplotlib.pyplot as plt import numpy as np rnd = np.random.default_rng(123) dx1, dy1 = 3, 2 dx2, dy2 = 3, 4 im1 = rnd.random((dy1, dx1)) im2 = rnd.random((dy2, dx2)) fig, (ax1, ax2) = plt.subplots(1, 2) ax1.imshow(im1, aspect='auto') ax2.imshow(im2, aspect='auto') plt.show()
方法2:手动匹配子图的显示高度
要保留图像原始长宽比同时让高度一致,可以计算两个图像的宽度比例,调整子图的宽度,让图像高度对齐:
import matplotlib.pyplot as plt import numpy as np rnd = np.random.default_rng(123) dx1, dy1 = 3, 2 dx2, dy2 = 3, 4 # 计算两个图像的宽高比 aspect1 = dx1 / dy1 aspect2 = dx2 / dy2 # 按高度一致的比例设置子图宽度比 width_ratio = [aspect1, aspect2] fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 3), gridspec_kw={'width_ratios': width_ratio}) ax1.imshow(im1) ax2.imshow(im2) plt.tight_layout() plt.show()
这个方法通过gridspec_kw的width_ratios参数,根据图像的宽高比调整子图宽度,保证图像显示高度相同,同时保留原始比例。
方法3:使用Axes.set_box_aspect
Matplotlib 3.3+支持set_box_aspect方法,可以直接指定子图的宽高比,让两个子图的高度对应的比例匹配:
import matplotlib.pyplot as plt import numpy as np rnd = np.random.default_rng(123) dx1, dy1 = 3, 2 dx2, dy2 = 3, 4 fig, (ax1, ax2) = plt.subplots(1, 2) ax1.imshow(im1) ax2.imshow(im2) # 设置子图的宽高比等于图像的宽高比 ax1.set_box_aspect(dy1/dx1) ax2.set_box_aspect(dy2/dx2) # 调整布局 plt.tight_layout() plt.show()
关于subplots的设计行为
是的,这是设计行为。subplots创建的子图本身的axes区域尺寸是一致的,但imshow默认的aspect='equal'会强制图像像素为正方形,所以当图像的长宽比不同时,显示的图像高度/宽度会被限制,导致视觉上子图高度不一致。
内容的提问来源于stack exchange,提问作者divenex
相关产品推荐
相关产品推荐

