Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make a movie out of a set of images stacked in a numpy array?

I'm trying to make a movie (or anything that would show the results sequentially) out of a set of 2d numpy arrays that are stacked into a 3rd dimension.

To illustrate what I'm talking about imagine a 9x3x3 numpy array where we have a sequence of 9 different 3x3 arrays stacked as below:

import numpy as np
#creating an array where a position is occupied by
# 1 and the others are zero
a = [[[0,0,1],[0,0,0],[0,0,0]],[[0,1,0],[0,0,0],[0,0,0]], [[1,0,0],[0,0,0],[0,0,0]], [[0,0,0],[0,0,1],[0,0,0]], [[0,0,0],[0,1,0],[0,0,0]], [[0,0,0],[1,0,0],[0,0,0]], [[0,0,0],[0,0,0],[0,0,1]], [[0,0,0],[0,0,0],[0,1,0]], [[0,0,0],[0,0,0],[1,0,0]]]
a = np.array(a)

So that a[0], ... a[n] would return something like:

In [10]: a[1]
Out[10]: 
array([[0, 1, 0],
       [0, 0, 0],
       [0, 0, 0]])

But changing the position of 1 and a simple plot made with the following lines:

img = plt.figure(figsize = (8,8))
    plt.imshow(a[0], origin = 'lower')
    plt.colorbar(shrink = 0.5)
    plt.show(img)

Would give the output:

Matrix first element

What then is the most appropriate way to create a movie, displaying results that are similar to the image above, with each of the results stacked in the first dimension of 'a' in order to observe how the changes take place over each different step (frame)?

Thanks for your attention and time!

like image 333
Chicrala Avatar asked Oct 15 '25 15:10

Chicrala


2 Answers

You can use matplotlib animation api.

Here's a quick prototype based on this example

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

a = [[[0,0,1],[0,0,0],[0,0,0]],
     [[0,1,0],[0,0,0],[0,0,0]],
     [[1,0,0],[0,0,0],[0,0,0]],
     [[0,0,0],[0,0,1],[0,0,0]],
     [[0,0,0],[0,1,0],[0,0,0]],
     [[0,0,0],[1,0,0],[0,0,0]],
     [[0,0,0],[0,0,0],[0,0,1]],
     [[0,0,0],[0,0,0],[0,1,0]],
     [[0,0,0],[0,0,0],[1,0,0]]]
a = np.array(a)

fig, ax = plt.subplots(figsize=(4, 4))

frame = 0
im = plt.imshow(a[frame], origin='lower')
plt.colorbar(shrink=0.5)

def update(*args):
    global frame

    im.set_array(a[frame])

    frame += 1
    frame %= len(a)

    return im,

ani = animation.FuncAnimation(fig, update, interval=500)
plt.show()

You can also save them as a gif with ImageMagickFileWriter, just replacing the last two lines with

ani = animation.FuncAnimation(fig, update, len(a))
writer = animation.ImageMagickFileWriter(fps=2)
ani.save('movie.gif', writer=writer) 

matplotlib animated gif

like image 195
filippo Avatar answered Oct 18 '25 06:10

filippo


You could create a gif from the output using imageio:

import numpy as np
import matplotlib.pyplot as plt
import imageio

a = [[[0,0,1],[0,0,0],[0,0,0]], 
     [[0,1,0],[0,0,0],[0,0,0]], 
     [[1,0,0],[0,0,0],[0,0,0]], 
     [[0,0,0],[0,0,1],[0,0,0]], 
     [[0,0,0],[0,1,0],[0,0,0]], 
     [[0,0,0],[1,0,0],[0,0,0]], 
     [[0,0,0],[0,0,0],[0,0,1]], 
     [[0,0,0],[0,0,0],[0,1,0]], 
     [[0,0,0],[0,0,0],[1,0,0]]]

a = np.array(a)

images = []

for array_ in a:
    file_path = "C:\file\path\image.png"

    img = plt.figure(figsize = (8,8))
    plt.imshow(array_, origin = 'lower')
    plt.colorbar(shrink = 0.5)

    plt.savefig(file_path) #Saves each figure as an image
    images.append(imageio.imread(file_path)) #Adds images to list
    plt.clf()

plt.close()
imageio.mimsave(file_path + ".gif", images, fps=1) #Creates gif out of list of images

enter image description here

like image 30
iacob Avatar answered Oct 18 '25 07:10

iacob



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!