You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 20:34:51