I'm trying to create an animation with matplotlib.
I have the following code:
import math
import numpy as np
import matplotlib as mpl
from matplotlib import pyplot as plt
from matplotlib import animation as ani
import ffmpeg
xValues = np.empty((4, 100)) # Initialize the vectors
yValues = np.empty((4, 100))
for i in np.arange(100): # Populate the vectors
xValues[:,i] = np.random.random(4)
yValues[:,i] = np.random.random(4)
k = 0 # Initialisation of k
myFig, ax = plt.subplots(figsize=(8,5))
p, = ax.plot([],[])
def animFunc(j): # Animation function
global k, p
j = int(j)
p.remove()
p, = ax.plot(xValues[:,k],yValues[:,k])
p.set_data(xValues[:,k],yValues[:,k])
k += 1
return p,
animator = ani.FuncAnimation(myFig, animFunc, interval=1, blit=True, repeat=False, frames=100)
animator.save('my_video.mp4', writer='ffmpeg', fps=50, bitrate=1000)
I am basically plotting two vectors xValues,yValues which have size 100 along axis 1.
When I run the code, the video is created, but I get the following error:
Traceback (most recent call last):
File "C:\...\...\my_code.py", line 30, in <module>
animator.save('my_video.mp4', writer='ffmpeg', fps=50, bitrate=1000)
File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\matplotlib\animation.py", line 1152, in save
anim._draw_next_frame(d, blit=False)
File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\matplotlib\animation.py", line 1192, in _draw_next_frame
self._draw_frame(framedata)
File "C:\Users\User\AppData\Local\Programs\Python\Python37\lib\site-packages\matplotlib\animation.py", line 1755, in _draw_frame
self._drawn_artists = self._func(framedata, *self._args)
File "C:\...\...\my_code.py", line 24, in animFunc
p, = ax.plot(xValues[:,k],yValues[:,k])
IndexError: index 100 is out of bounds for axis 1 with size 100
Seemingly, the function is trying to repeat the animation after the last frame (then the repetition starts at the index k = 100, which is too large for xValues, yValues). But why does it do so? I have set repeat=False in the declaration.
Also, how would you tune the bitrate parameter? Is 1000 a good value?
EDIT 1: JohanC's solution works fine, I tried to implement a dummy InitFunction (the ax objects are initialised once, out of any function) and to substitute k with j and now there's no additional calls to the animation!