Matplotlib中如何将imshow图像嵌入另一幅?extent参数使用异常
问题原因
你遇到的问题核心在于:
- 同一个
Axes对象下,第二次调用ax.imshow()时指定的extent会自动修改当前Axes的显示范围(xlim/ylim),使其匹配新的extent参数。这导致第一次绘制的大图像超出了新的显示范围,所以你只能看到第二次的小图像,而非叠加效果。 - 直接在同一Axes叠加
imshow无法实现“嵌入”的视觉效果,因为Matplotlib会优先匹配最新的绘图范围。
正确实现方式
要实现一幅图像嵌入另一幅的效果,推荐使用插入子轴(inset axes)——在主Axes内部创建一个独立的子Axes专门显示小图像,这样两个图像的显示范围互不干扰,能精准控制嵌入位置。
修改后的代码如下:
import urllib.request from PIL import Image import numpy as np import matplotlib.pyplot as plt # 获取图像 url = r"https://upload.wikimedia.org/wikipedia/en/9/9d/The_Tilled_Field.jpg" img = np.array(Image.open(urllib.request.urlopen(url))) # 创建主图和主Axes fig, ax = plt.subplots(figsize=(4.5, 6.4)) ax.imshow(img) # 设置刻度和网格 ax.set_xticks(range(0,1300,100), minor=False) ax.set_xticks(range(0,1300,20), minor=True) ax.set_yticks(range(0,900,100), minor=False) ax.set_yticks(range(0,900,20), minor=True) ax.grid(which='minor', color='grey') # 创建插入子Axes:参数为[左, 下, 宽, 高],范围0-1(相对主Axes的比例) inset_ax = ax.inset_axes([0.3, 0.2, 0.15, 0.15]) # 位置可自行调整 # 也可以用绝对像素坐标:inset_ax = ax.inset_axes([400, 200, 128, 90], transform=ax.transData) # 在子Axes中显示小图像,关闭子轴的刻度和边框 inset_ax.imshow(img) inset_ax.set_xticks([]) inset_ax.set_yticks([]) inset_ax.spines[:].set_visible(False) plt.show()
如果一定要在同一Axes中叠加(不推荐,易出现范围混乱),可以手动锁定主Axes的显示范围,并调整小图像的层级确保显示在上方:
# 绘制主图像后锁定显示范围 ax.imshow(img) ax.set_xlim(0, img.shape[1]) ax.set_ylim(img.shape[0], 0) # imshow默认y轴反向,需对应设置 # 绘制小图像,指定extent和z-order确保在主图像上方 ax.imshow(img, extent=[400,528,200,290], zorder=10) # 后续刻度、网格设置不变
关键说明
ax.inset_axes()是实现嵌入效果的标准方式,创建的子Axes完全独立,不会影响主Axes的显示范围,还能自由调整位置和大小。- 若使用同一Axes叠加,必须手动设置
xlim/ylim匹配主图像范围,同时通过zorder参数确保小图像显示在主图像之上。
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

