在 matplotlib 图上操纵和动画图像

manipulating and animating an image on a matplotlib plot

我正在使用 matplotlib 制作行星围绕恒星运动的动画。 我画了一个代表地球的简单小圆圈,然后我将 funcanimation 与 animate() 函数一起使用,每次都会改变圆圈的中心,就像在这个网站上所做的那样:https://nickcharlton.net/posts/drawing-animating-shapes-matplotlib.html.

现在我正在尝试使用图像文件而不是圆圈,但我几乎不知道如何在图上绘制图像,而且真的不知道如何让它在上面移动

有什么想法吗?

谢谢

像这样的东西会起作用:

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.image import BboxImage
from matplotlib.transforms import Bbox, TransformedBbox

# make figure + Axes
fig, ax = plt.subplots()

# make initial bounding box
bbox0 = Bbox.from_bounds(0, 0, 1, 1)
# use the `ax.transData` transform to tell the bounding box we have given
# it position + size in data.  If you want to specify in Axes fraction
# use ax.transAxes
bbox = TransformedBbox(bbox0, ax.transData)
# make image Artist            
bbox_image = BboxImage(bbox,
                       cmap=plt.get_cmap('winter'),
                       norm=None,
                       origin=None,
                       **kwargs
                       )
# shove in some data
a = np.arange(256).reshape(1, 256)/256.

bbox_image.set_data(a)
# add the Artist to the Axes
ax.add_artist(bbox_image)
# set limits
ax.set_xlim(0, 10)
ax.set_ylim(0, 10)

# loop over new positions
for j in range(50):
    x = j % 10
    y = j // 10
    # make a new bounding box
    bbox0 = Bbox.from_bounds(x, y, 1, 1)
    bbox = TransformedBbox(bbox0, ax.transData)
    bbox_image.bbox = bbox
    # re-draw the plot
    plt.draw()
    # pause so the gui can catch up
    plt.pause(.1)

它可能比需要的复杂一点,您确实应该使用动画框架而不是 pause

我想给你 +1,但我的声誉还不允许。 非常感谢代码,我通过修改此行成功地将导入的图像放入您使用的艺术家中:

bbox_image.set_data(mpimg.imread("C:\image.png"))

注意我也添加了这个

Import matplotlib.image as mpimg

但是当我尝试使用 funcanimation 对此进行动画处理时,仍然有些不对劲,我收到一个错误,这是我的代码(您修改过的):

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.image import BboxImage
from matplotlib.transforms import Bbox, TransformedBbox
import matplotlib.image as mpimg

from matplotlib import animation


# make figure + Axes
fig, ax = plt.subplots()

# make initial bounding box
bbox0 = Bbox.from_bounds(0, 0, 1, 1)
# use the `ax.transData` transform to tell the bounding box we have given
# it position + size in data.  If you want to specify in Axes fraction
# use ax.transAxes
bbox = TransformedBbox(bbox0, ax.transData)
# make image Artist            
bbox_image = BboxImage(bbox,
                       cmap=plt.get_cmap('winter'),
                       norm=None,
                       origin=None

                       )


bbox_image.set_data(mpimg.imread("C:\icon-consulting.png"))
# add the Artist to the Axes
ax.add_artist(bbox_image)
# set limits
ax.set_xlim(-10, 10)
ax.set_ylim(-10, 10)


def animate(i):
    bbox0 = Bbox.from_bounds(i, i, 1, 1)
    bbox = TransformedBbox(bbox0, ax.transData)
    bbox_image.bbox = bbox
    return bbox_image



anim = animation.FuncAnimation(fig, animate,  
                               frames=100000, 
                               interval=20,
                               blit=True)

plt.show()

它告诉我错误:'BboxImage' 对象不可迭代 我想只有这个 BboxImage 的位置部分应该 returned 我习惯于通过添加昏迷来使用 Line2D objets,例如:return lineobject, 这意味着只有元组的第一个元素将被 returned,但我不知道如何使用 BboxImage

来完成

事实上,我可以像你第一次那样简单地使用循环,但也许你知道如何将其改编为有趣的动画?

编辑:

我使用 bbox 方法再次修改了您的代码:

for j in range(5000):
x = 2*np.sin(np.radians(j))
y = 2*np.cos(np.radians(j))
# make a new bounding box
bbox0.set_points([[x,y],[x+1,y+1]])
# re-draw the plot
plt.draw()
# pause so the gui can catch up

plt.pause(0.1)

然后我可以通过这种方式将其转换为使用 funcanimation :

def animate(i):
x = 2*np.sin(np.radians(i))
y = 2*np.cos(np.radians(i))
# make a new bounding box
bbox0.set_points([[x,y],[x+1,y+1]])

return bbox0.get_points()

anim = animation.FuncAnimation(fig, animate,  
                           frames=100000, 
                           interval=20,
                           blit=True)

plt.show()

这给了我一个错误:'list' 对象没有属性 'axes' 这是我在 animate 函数中做的 return,我猜 returned 值应该以某种方式转换......你知道我该怎么做吗?谢谢