在不改变轴的情况下缩放matplotlib中的图像

Cha*_*net 6 python matplotlib

我有一个显示情节的GUI.我想将该情节与现有图像相匹配.我使用以下方式在图表下显示图像:

myaxe.plot(...)
myaxeimage = myaxe.imshow(myimage, axpect='auto', extent=myaxe.axis(), zorder=-1)
Run Code Online (Sandbox Code Playgroud)

我已经能够使用图像的不透明度

myaxeimage.set_alpha()
Run Code Online (Sandbox Code Playgroud)

现在,我希望能够使用GUI放大和缩小图像并在图像中移动,而不会触及现有的绘图和轴,以便将其与我的绘图对齐.换句话说,我想缩放到给定sxsy因子,并将图像的原点放在给(x,y)定点,剪切图像的部分到轴外.我怎样才能做到这一点?

unu*_*tbu 7

有一个与matplotlib一起分发的水印示例有点类似.从该代码开始,我们可以修改如下:

用于ax.imshow首先绘制图像.我这样做是因为extent参数会影响最终范围ax.既然我们希望最终的范围受到它的支配,那么plt.plot(...)我们就把它放在最后.

myaximage = ax.imshow(im, aspect='auto', extent=(1,15,0.3,0.7), alpha=0.5, origin='upper', zorder=-1)
Run Code Online (Sandbox Code Playgroud)

而不是extent=myaxe.axis(),extent用来控制图像的位置和大小.extent=(1,15,0.3,0.7)将图像放在矩形中,(1, 0.3)左下角和(15, 0.7)右上角.

使用时origin='upper',[0,0]数组的索引im位于范围的左上角.随着origin='lower'它会被放置在左下角.


import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cbook as cbook
import matplotlib.image as image
np.random.seed(1)
datafile = cbook.get_sample_data('logo2.png', asfileobj=False)
im = image.imread(datafile)
fig, ax= plt.subplots()

myaximage = ax.imshow(im, aspect='auto', extent=(1,15,0.3,0.7), alpha=0.5, zorder=-1)
ax.plot(np.random.rand(20), '-o', ms=20, lw=2, alpha=1.0, mfc='orange')
ax.grid()
plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


如果你想扩展图像,并把它夹到情节的严重程度,你可能需要使用ax.set_xlimax.set_ylim,以及:

myaximage = ax.imshow(im, aspect='auto', extent=(-1,25,0.3,0.7), alpha=0.5, zorder=-1,
                      origin='upper')

ax.plot(np.random.rand(20), '-o', ms=20, lw=2, alpha=1.0, mfc='orange')
ax.set_xlim(0,20)
ax.set_ylim(0,1)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


或者,为了进行更多控制,您可以使用myaximage.set_clip_path以下方法将图像剪切为任意路径:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cbook as cbook
import matplotlib.image as image
import matplotlib.patches as patches
np.random.seed(1)
datafile = cbook.get_sample_data('logo2.png', asfileobj=False)
im = image.imread(datafile)
fig, ax= plt.subplots()

myaximage = ax.imshow(im, aspect='auto', extent=(-5,25,0.3,0.7), 
                      alpha=0.5, origin='upper',
                      zorder=-2)
# patch = patches.Circle((300,300), radius=100)
patch = patches.Polygon([[5, 0.4], [15, 0.4], [15, 0.6], [5, 0.6]], closed=True,
                        transform=ax.transData)
myaximage.set_clip_path(patch)
ax.plot(np.random.rand(20), '-o', ms=20, lw=2, alpha=1.0, mfc='orange', 
        zorder=-1)

ax.set_xlim(0, 20)
ax.set_ylim(0, 1)

plt.show()
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


Cha*_*net 0

最后,我遵循 tcaswell 的建议并使用了 2 个不同的轴。这样,我只需使用图像轴的set_xlim()set_ylim()来更改图像的原点和/或缩放系数。我为了获得图下方的图像,而不用图的框架隐藏它,我删除了图的框架并使用图像轴的框架。我还隐藏了图像轴上的刻度。

from matplotlib import pyplot

f = pyplot.figure()
a = f.add_subplot(111, frameon=False) # Remove frame
a.plot(...)

myimg = pyplot.imread(...)
imgaxes = f.add_axes(a.get_position(), # new axes with same position
    label='image', # label to ensure imgaxes is different from a
    zorder=-1, # put image below the plot
    xticks=[], yticks=[]) # remove the ticks
img = imgaxes.imshow(myimg, aspect='auto') # ensure image takes all the place

# now, to modify things
img.set_alpha(...)
imgaxes.set_xlim((x1, x2)) # x1 and x2 must be calculated from
                           # image size, origin, and zoom factor
Run Code Online (Sandbox Code Playgroud)