Question

Making an image move in matplotlib

I'm trying to have an image rotate and translate in matplotlib according to a predefined pattern.

I'm trying to use FuncAnimation and Affine2D to achieve this. My code looks something like this :

from matplotlib.animation import FumcAnimation
from matplotlib.transforms import Affine2D
from matplotlib import pyplot as plt

fig, ax = plt.subplots()
img = ax.imgshow(plt.imread("demo.png"),aspect="equal")

def update(i):
    if i>0: img.set_transform(Affine2D().translate(1,0))
    return img

anim=FuncAnimation(fig,update,frames=(0,1))
plt.show()

Instead of the image moving right, it disappears.

 3  41  3
1 Jan 1970

Solution

 0

You're not using the value of the frames (0 or 1) to make the movement and that's not the only issue. So, assuming you want to simultaneously translate the image (to the right) and rotate_deg (relative to the center), you can do something like below :

import matplotlib.pyplot as plt
import matplotlib.transforms as mtransforms
from matplotlib.animation import FuncAnimation

img = plt.imread("mpl_log.png")
W, H, *_ = img.shape

fig, ax = plt.subplots(figsize=(10, 5))

# feel free to readapt..
ax.grid()
ax.patch.set_facecolor("whitesmoke")
aximg = ax.imshow(img, aspect="equal")
ax.set(xlim=(-W // 2, W * 7), ylim=(-H, H * 2))


def move(frame):
    transfo = mtransforms.Affine2D()
    (
        transfo
        # centered rotation
        .translate(-W / 2, -H / 2)
        .rotate_deg(frame % 190)
        .translate(W / 2, H / 2)
        # translation to the right
        .translate(frame, 0)
    )

    aximg.set_transform(transfo + ax.transData)
    return (aximg,)


anim = FuncAnimation(fig, move, frames=range(0, W * 6, 100))

Output (fps=10) :

enter image description here

2024-07-08
Timeless