0

I have two images, and I want to animate a "swipe down" effect where each row of image 2 replaces each row of image 1. I think this involves substituting each pixel of 1st row of the 1st image by the 2nd one from top to bottom.

Here's a simple example that shows two grayscale images:

import matplotlib.pyplot as plt
import numpy as np

image2 = np.array([[200, 200, 200], [200, 200, 200], [200, 200, 200]])
image1 = np.array([[100, 100, 100], [100, 100, 100], [100, 100, 100]])

fig, ax = plt.subplots(2, 1)
ax[0].imshow(image2, cmap='gray', vmin=0, vmax=255)
ax[1].imshow(image1, cmap='gray', vmin=0, vmax=255)
plt.show()

Two squares. The top is labeled 2nd Image and is light gray. The bottom is a darker gray and is labeled 1st Image

But then I'm stuck. I'd like to animate the steps but I'm not sure how. Is it possible to do:

image2[row,column] = image1[row,column]
Alexander L. Hayes
  • 3,892
  • 4
  • 13
  • 34

1 Answers1

0

Assuming that image1 and image2 are the same size, we can stack them on top of each other with np.vstack, roll the matrix, and plot the last N rows. Here's the basic idea:

N = image2.shape[0]                 # How many rows to plot?
im = np.vstack([image2, image1])    # Stack matrices
image = ax.imshow(im[N:])           # imshow the last N rows

# Repeat:
im = np.roll(im, shift=-1, axis=0)  # -1 for up, 1 for down
Original ronin.png Swipe Up (-1) Swipe Down (+1)
static image of ronin, a husky labrador gif of ronin shifting up only to be replaced by the same image gif of ronin shifting down only to be replaced by the same image

Full example using the trick to turn whitespace off in matplotlib figures.

import matplotlib.animation as animation
import matplotlib.pyplot as plt
from matplotlib import image
import numpy as np

image2 = image.imread("ronin.png")
image1 = image.imread("ronin.png")

# Trick to turn borders off in matplotlib
# https://stackoverflow.com/questions/37809697/remove-white-border-when-using-subplot-and-imshow-in-python-matplotlib
fig = plt.figure()
fig.set_size_inches(image1.shape[1] / image1.shape[0], 1, forward=False)
ax = plt.Axes(fig, [0., 0., 1., 1.])
ax.set_axis_off()
fig.add_axes(ax)

N = image2.shape[0]                 # How many rows to plot?
im = np.vstack([image2, image1])    # Stack matrices
image = ax.imshow(im[N:])           # imshow the last N rows

def animate(i):
    global im
    im = np.roll(im, shift=-1, axis=0)
    image.set_array(im[N:])
    return [image]

ani = animation.FuncAnimation(fig, animate, N, repeat=False)
ani.save("my_animation.gif", fps=60)
Alexander L. Hayes
  • 3,892
  • 4
  • 13
  • 34