How to adjust animation duration
Asked Answered
C

2

7

the code here below shows and saves an animation of random matrices in succession. My question is how can I adjust the duration of the animation that I save. The only parameters that I have here fps, and dpi control first how many seconds a frame remains and the second controls the quality of the image. What I want is to actually control the number of frames that are going to be saved in terms of the matrices the number of them that are actually stored.

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

fig = plt.figure()

N = 5

A = np.random.rand(N,N)
im = plt.imshow(A)

def updatefig(*args):
    im.set_array(np.random.rand(N,N))
    return im,

ani = animation.FuncAnimation(fig, updatefig, interval=200, blit=True) 

ani.save('try_animation.mp4', fps=10, dpi=80) #Frame per second controls speed, dpi       controls the quality 
plt.show()

I am wonderinf if I should add more parameters. I tried to look for the appropriate one in the class documentation in matplotlib but I was unsuccessful:

http://matplotlib.org/api/animation_api.html#module-matplotlib.animation

Curr answered 25/2, 2014 at 10:0 Comment(0)
Z
11

The documentation reveals that FuncAnimation accepts an argument frames, which controls the total number of frames played. Your code could thus read

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

fig = plt.figure()

N = 5

A = np.random.rand(N,N)
im = plt.imshow(A)

def updatefig(*args):
    im.set_array(np.random.rand(N,N))
    return im,

ani = animation.FuncAnimation(fig, updatefig, frames=10, interval=200, blit=True) 

ani.save('try_animation.mp4', fps=10, dpi=80) #Frame per second controls speed, dpi       controls the quality 
plt.show()

to play 10 frames.

Zacheryzack answered 25/2, 2014 at 10:26 Comment(5)
Indeed the documentation says: frames can be a generator, an iterable, or a number of frames.Curr
Indeed the documentation says: frames can be a generator, an iterable, or a number of frames. So my mistake, I read the beginning and was not careful enough. On the other hand your solution does provide the right result -the file that it saves has the proper duration equal to frames / fps. However the file that is shown -not the one that is saved- does not follow this pattern it just keeps on showing new frames in a non periodic way. Any idea on why is this?Curr
What do you mean by "in a non periodic way"?Zacheryzack
If I have ten frames I was expecting that the showed animation repeated itself every ten frames -or stop at least. By non-periodic I mean that the frames are different with that period of 10 frame(11) != frame(1)Curr
what if frames is not set? just to let the animation loop back. Is there a way to cap the duration in animation.save() call itself?Aparejo
C
15

Years later I have built this is example that I come back to every time that I need to see how the parameters of the animation relate between themselves. I decided to share it here for whoever may find it useful.

tl/dr:

  • For the saved animation the duration is going to be frames * (1 / fps) (in seconds)
  • For the display animation the duration is going to be frames * interval / 1000 (in seconds)

The code bellow allows you to play with this setting in an environment that gives immediate visual feedback.

This code builds a clock that ticks according to the parameters:

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


fig = plt.figure(figsize=(16, 12))
ax = fig.add_subplot(111)
# You can initialize this with whatever
im = ax.imshow(np.random.rand(6, 10), cmap='bone_r', interpolation='nearest')


def animate(i):
    aux = np.zeros(60)
    aux[i] = 1
    image_clock = np.reshape(aux, (6, 10))
    im.set_array(image_clock)

ani = animation.FuncAnimation(fig, animate, frames=60, interval=1000)
ani.save('clock.mp4', fps=1.0, dpi=200)
plt.show()

This will generate and save an animation that will look like this:

enter image description here

So the point is that the black square will move along the big white square as the time is passing. There are 60 white boxes so you can build a clock that goes over it in a minute.

Now, the important thing to note is that there are two parameters that determine how fast the black box would move: interval in the animation.FuncAnimation function and 'fps' in the ani.save function. The first controls the speed in the animation that you will display and the second in the animation that you will save.

As the code above stands you will generate 60 frames and they are displayed at 1 frame per second. That means that the clock ticks every second. If you want the saved animation clock to tick every two seconds then you should set fps=0.5. If you want the displayed animation clock to click every two seconds you should set interval=2000.

[I will edit the longer explanation as soon as I have time]

Curr answered 19/8, 2016 at 14:5 Comment(1)
So if i have 2 lists, say x and y, corresponding to the coordinates of a pendulum through time, say from 0 sec to 10 sec, and i want the displayed animation to have a duration of 10 sec (simulate real time), how should i set up the parameters then? Ive been trying and i just cant get it to work as i want..Antifebrile
Z
11

The documentation reveals that FuncAnimation accepts an argument frames, which controls the total number of frames played. Your code could thus read

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

fig = plt.figure()

N = 5

A = np.random.rand(N,N)
im = plt.imshow(A)

def updatefig(*args):
    im.set_array(np.random.rand(N,N))
    return im,

ani = animation.FuncAnimation(fig, updatefig, frames=10, interval=200, blit=True) 

ani.save('try_animation.mp4', fps=10, dpi=80) #Frame per second controls speed, dpi       controls the quality 
plt.show()

to play 10 frames.

Zacheryzack answered 25/2, 2014 at 10:26 Comment(5)
Indeed the documentation says: frames can be a generator, an iterable, or a number of frames.Curr
Indeed the documentation says: frames can be a generator, an iterable, or a number of frames. So my mistake, I read the beginning and was not careful enough. On the other hand your solution does provide the right result -the file that it saves has the proper duration equal to frames / fps. However the file that is shown -not the one that is saved- does not follow this pattern it just keeps on showing new frames in a non periodic way. Any idea on why is this?Curr
What do you mean by "in a non periodic way"?Zacheryzack
If I have ten frames I was expecting that the showed animation repeated itself every ten frames -or stop at least. By non-periodic I mean that the frames are different with that period of 10 frame(11) != frame(1)Curr
what if frames is not set? just to let the animation loop back. Is there a way to cap the duration in animation.save() call itself?Aparejo

© 2022 - 2024 — McMap. All rights reserved.