如何在 matplotlib 中的每个子图中嵌入图像?

How can I embed an image on each of my subplots in matplotlib?

我正在尝试在每个子图的角落放置一个小箭头。下面是我正在使用的示例代码:

import matplotlib.pyplot as plt
import matplotlib.image as image
from numpy import linspace

xs = linspace(0, 1, 100)
im = image.imread('arrow.png')

def multi_plot():
    fig, axes = plt.subplots(4, 1)
    x = 0
    for axis in axes:
        axis.plot(xs, xs**2)
        axis.imshow(im, extent=(0.4, 0.6, .5, .7), zorder=-1, aspect='auto')
    plt.show()

multi_plot()

不幸的是,这会产生 4 个完全由箭头控制的子图,并且看不到图本身。

示例输出 - 不正确:

我需要做什么才能让每个单独的子图都有一个 图像并且可以看到情节本身?

您会注意到 x 和 y 轴上的限制已设置为 imshow 的范围,而不是 0-1,您的绘图需要看到该线。

您可以使用 axis.set_xlim(0, 1)axis.set_ylim(0, 1) 来控制它。

import matplotlib.pyplot as plt
import matplotlib.image as image
from numpy import linspace

xs = linspace(0, 1, 100)
im = image.imread('arrow.png')

def multi_plot():
    fig, axes = plt.subplots(4, 1)
    x = 0
    for axis in axes:
        axis.plot(xs, xs**2)
        axis.imshow(im, extent=(0.4, 0.6, .5, .7), zorder=-1, aspect='auto')
        axis.set_xlim(0, 1)
        axis.set_ylim(0, 1)
    plt.show()

multi_plot()

或者,如果您想在数据周围保留 matplotlib 默认使用的额外 5% 的边距,您可以将 imshow 命令移动到 plot 命令之前,然后后者将控制轴限制。

import matplotlib.pyplot as plt
import matplotlib.image as image
from numpy import linspace

xs = linspace(0, 1, 100)
im = image.imread('arrow.png')

def multi_plot():
    fig, axes = plt.subplots(4, 1)
    x = 0
    for axis in axes:
        axis.imshow(im, extent=(0.4, 0.6, .5, .7), zorder=-1, aspect='auto')
        axis.plot(xs, xs**2)
    plt.show()

multi_plot()

我认为值得考虑使用 loc 参数将图像放在一个盒子中并将其放置在类似于图例的位置。优点是您根本不需要关心范围和数据坐标。您也不需要关心缩放或平移绘图时发生的情况。此外,它允许将图像保持在其原始分辨率(下面代码中的zoom=1)。

import matplotlib.pyplot as plt
import matplotlib.image as image
from numpy import linspace

from matplotlib.offsetbox import OffsetImage,AnchoredOffsetbox


xs = linspace(0, 1, 100)
im = image.imread('arrow.png')


def place_image(im, loc=3, ax=None, zoom=1, **kw):
    if ax==None: ax=plt.gca()
    imagebox = OffsetImage(im, zoom=zoom*0.72)
    ab = AnchoredOffsetbox(loc=loc, child=imagebox, frameon=False, **kw)
    ax.add_artist(ab)


def multi_plot():
    fig, axes = plt.subplots(4, 1)
    for axis in axes:
        axis.plot(xs, xs**2)
        place_image(im, loc=2, ax=axis, pad=0, zoom=1)
    plt.show()

multi_plot()