Saving animations using ffmpeg and matplotlib - python

im new in here and new in python, im doing some animations with animation.FuncAnimation of matplotliib. The animation works perfectly but i´m having problems saving the animations. here is the part of the code of the animation.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig, ax = plt.subplots()
line, = ax.plot(range(N),sin(x[0,:]),'o-')
ax.axis([0,1,-1,1])
def animate(i):
line.set_ydata(sin(x[i,:])) # update the data
return line,
def init():
line.set_ydata(np.ma.array(x[0,:], mask=True))
return line,
ani = animation.FuncAnimation(fig, animate, np.arange(1, 10000),
interval=25, init_func=init, blit=True)
ani.save('2osc.mp4', writer="ffmpeg")
plt.show()
where x[:,:] is previously set. ani.save is saving every frame of the animation as a .npg image instade of saving the movie. I dont know if this is how it is suposed to work and i have to do the movie with the .npg with another program or if im doing something wrong.
Obs: i've previously installed ffmpeg and it seems to be working just fine.

For me this code seems to be running fine:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig, ax = plt.subplots(1,1)
x=np.linspace(np.pi,4*np.pi,100)
N=len(x)
ax.set_xlim(len(x))
ax.set_ylim(-1.5,1.5)
line, = ax.plot([],[],'o-')
def init():
line.set_ydata(np.ma.array(x[:], mask=True))
return line,
def animate(i, *args, **kwargs):
y=np.sin(x*i)
line.set_data(np.arange(N),y) # update the data
return line,
ani = animation.FuncAnimation(fig, animate, init_func=init,
frames=100, interval=10, blit= False, repeat = False)
ani.save('2osc.mp4', writer="ffmpeg")
fig.show()
You can install the ffmpeg library by using:
sudo apt-get install ffmpeg

Related

Animation can only display the firstframe [duplicate]

This question already has answers here:
Animation in iPython notebook
(4 answers)
Closed 4 years ago.
from matplotlib import pyplot as plt
from matplotlib import animation
import numpy as np
fig, ax = plt.subplots()
x = np.arange(0, 2*np.pi, 0.01)
line, = ax.plot(x, np.sin(x))
def animate(i):
line.set_ydata(np.sin(x + i/10.0))
return line,
def init():
line.set_ydata(np.sin(x))
return line,
ani = animation.FuncAnimation(fig=fig,
func=animate,
frames=100,
init_func=init,
interval=20,
blit=False)
plt.show()
I coded in jupyter Notebook,matplotlib's version is 2.2.0 and python's is 2.7.
I tried to display a animation,but the output is only the first frame,a static picture.
I cannot find the error.
This is the static picture:
Jupyter notebooks output pngs which cannot be animated. You can use Javascript to animate a plot in a notebook.
from matplotlib import pyplot as plt
from matplotlib import animation
import numpy as np
from IPython.display import HTML
fig, ax = plt.subplots()
x = np.arange(0, 2*np.pi, 0.01)
line, = ax.plot(x, np.sin(x))
def animate(i):
line.set_ydata(np.sin(x + i/10.0))
return line,
def init():
line.set_ydata(np.sin(x))
return line,
ani = animation.FuncAnimation(fig=fig,
func=animate,
frames=100,
init_func=init,
interval=20,
blit=False)
HTML(ani.to_jshtml())

Matplotlib Animate a box plot

I'm trying to animate a box plot as data shifts over a time series.
I'm working off the matplotlib animate examples, which show how it works with the plot function, but that doesn't seem to carry over for a boxplot function:
Code Works below, but changing the two lines to box plot gives me errors
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig, ax = plt.subplots()
line, = ax.plot(np.arange(10)) # <-- ax.boxplot(np.arange(10))
ax.set_ylim(0, 20)
def update(data):
line.set_ydata(data) # < -- line = ax.boxplot(data)?
return line,
def data_gen():
i = 0
while True:
yield np.arange(10) + i
i += .1
ani = animation.FuncAnimation(fig, update, data_gen, interval=100)
plt.show()
Boxplot also doesn't seem to have a "set_data" function, or an "animated=True" parameter.
Essentially I'd like the animation to work the same as above, but depicting a box plot instead of a line plot.
I figured it out myself: The idea can be to clear the axes, and in each frame draw a new boxplot as shown below.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig, ax = plt.subplots()
# line, = ax.boxplot(np.arange(10)) <-- not needed it seems
ax.set_ylim(0, 20)
def update(data):
ax.cla() # <-- clear the subplot otherwise boxplot shows previous frame
ax.set_ylim(0, 20)
ax.boxplot(x=data)
def data_gen():
i = 0
while True:
yield np.arange(10) + i
i += .1
ani = animation.FuncAnimation(fig, update, data_gen, interval=100)
plt.show()
# Unset socks proxy
unset all_proxy
unset ALL_PROXY
# Install missing dependencies:
pip install pysocks
# Reset proxy
source ~/.bashrc

Python: Graphing and animating multiple iterations of the same graph with Python

Hi I am trying to create a movie of 15 Gaussian graphs that move to the left (thats essentially what the code is suppose to do)
However, my idea for how to create the for loop to create the 15 graphs has not created more than 1, it only speeds up the animation.
A similar code worked on matlab. It created 15 different Gaussian curves.
Here is a sample of my code.
any help would be appreciated.
Thanks
import numpy as np
import matplotlib.pyplot as plt
plt.switch_backend('agg')
import matplotlib.animation as animation
Gamma=0.0005
q=1.6e-19
m=0.067*9e-31
B=10
Ec=(1.0567e-34)*B/m
#e=2.78
#E0=0+(1.0567e-34)*x*i/m
fig, ax = plt.subplots()
pass
x = np.arange(0, 3.4e-3, 1.7e-5) # x-array, third number is interval here, x is energy
line, = ax.plot(x, np.e**(-(x-((1.0567e-34)*1*1/m))**2/Gamma**2))
def animate(i):
for p in xrange(1,3):
line.set_ydata(np.e**((-(x-((1.0567e-34)*p*i/m))**2)/Gamma**2)) # update the data
return line,
#Init only required for blitting to give a clean slate.
def init():
line.set_ydata(np.ma.array(x, mask=True))
return line,
ani = animation.FuncAnimation(fig, animate, np.arange(0, 2, .01), init_func=init,
interval=10, blit=True)
Writer = animation.writers['ffmpeg']
writer = Writer(fps=20, metadata=dict(artist='Me'), bitrate=1800)
ani.save('QHanimati.mp4', writer=writer)
plt.show()
You currently have exactly one line in your code. This line gets updated. If you want to have more lines, you need to create more lines.
You then also need to update all of those lines.
(Since the role of p isn't clear from the example I took it as some incrementing number here. I also restricted this to 8 curves not to overcrowd the image.)
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
Gamma=0.0005
q=1.6e-19
m=0.067*9e-31
B=10
Ec=(1.0567e-34)*B/m
fig, ax = plt.subplots()
n = 8 # number of lines
x = np.arange(0, 3.4e-3, 1.7e-5)
lines = [ax.plot(x, np.e**(-(x-((1.0567e-34)*1*1/m))**2/Gamma**2))[0] for _ in range(n)]
def animate(i):
for ln, line in enumerate(lines):
p = (ln+1)/10.
line.set_ydata(np.e**((-(x-((1.0567e-34)*p*i/m))**2)/Gamma**2)) # update the data
return lines
#Init only required for blitting to give a clean slate.
def init():
for line in lines:
line.set_ydata(np.ma.array(x, mask=True))
return lines
ani = animation.FuncAnimation(fig, animate, np.arange(0, 2, .01), init_func=init,
interval=10, blit=True)
plt.show()

Why does the output of animation.FuncAnimation have to be bound to a name? [duplicate]

I am trying to do an animation using the FuncAnimation module, but my code only produces one frame and then stops. It seems like it doesn't realize what it needs to update. Can you help me what went wrong?
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
x = np.linspace(0,2*np.pi,100)
def animate(i):
PLOT.set_data(x[i], np.sin(x[i]))
print("test")
return PLOT,
fig = plt.figure()
sub = fig.add_subplot(111, xlim=(x[0], x[-1]), ylim=(-1, 1))
PLOT, = sub.plot([],[])
animation.FuncAnimation(fig, animate, frames=len(x), interval=10, blit=True)
plt.show()
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
x = np.linspace(0,2*np.pi,100)
fig = plt.figure()
sub = fig.add_subplot(111, xlim=(x[0], x[-1]), ylim=(-1, 1))
PLOT, = sub.plot([],[])
def animate(i):
PLOT.set_data(x[:i], np.sin(x[:i]))
# print("test")
return PLOT,
ani = animation.FuncAnimation(fig, animate, frames=len(x), interval=10, blit=True)
plt.show()
You need to keep a reference to the animation object around, otherwise it gets garbage collected and it's timer goes away.
There is an open issue to attach a hard-ref to the animation to the underlying Figure object.
As written, your code well only plot a single point which won't be visible, I changed it a bit to draw up to current index

How to embed matplotlib funcAnimation object within PyQT GUI [duplicate]

I am trying to do an animation using the FuncAnimation module, but my code only produces one frame and then stops. It seems like it doesn't realize what it needs to update. Can you help me what went wrong?
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
x = np.linspace(0,2*np.pi,100)
def animate(i):
PLOT.set_data(x[i], np.sin(x[i]))
print("test")
return PLOT,
fig = plt.figure()
sub = fig.add_subplot(111, xlim=(x[0], x[-1]), ylim=(-1, 1))
PLOT, = sub.plot([],[])
animation.FuncAnimation(fig, animate, frames=len(x), interval=10, blit=True)
plt.show()
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
x = np.linspace(0,2*np.pi,100)
fig = plt.figure()
sub = fig.add_subplot(111, xlim=(x[0], x[-1]), ylim=(-1, 1))
PLOT, = sub.plot([],[])
def animate(i):
PLOT.set_data(x[:i], np.sin(x[:i]))
# print("test")
return PLOT,
ani = animation.FuncAnimation(fig, animate, frames=len(x), interval=10, blit=True)
plt.show()
You need to keep a reference to the animation object around, otherwise it gets garbage collected and it's timer goes away.
There is an open issue to attach a hard-ref to the animation to the underlying Figure object.
As written, your code well only plot a single point which won't be visible, I changed it a bit to draw up to current index

Categories

Resources