Python FuncAnimation not recognizing update - python

I'm learning how to animate in python for one of my projects and I'm basing my code off of the following example from here.
My adaption of their code goes as follows:
import numpy as np
import h5py, os, glob, sys, time
import matplotlib as mpl
mpl.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
def update(i):
for j in np.arange(0,10):
for k in np.arange(0,10):
for channel in ["N","E"]:
x = some_x_value
y = some_y_value
line = plt.loglog(x,y)
ax.set_xlabel(label)
return line, ax
if __name__ == "__main__":
fig, ax = plt.subplots()
anim = FuncAnimation(fig, update, frames=np.arange(0,10), interval=200)
anim.save('Test.gif', dpi=80, writer='imagemagick')
And when I try to run my script I get the following error:
Name Error: name 'update' is not defined.
As I said before, I'm still learning how to animate and don't understand all of what's going on in the code tutorial I found. However, I'm very confused as to why update isn't recognized at all as the way I call update seems to be exactly the same as what's in the tutorial.

import numpy as np
import matplotlib as mpl
mpl.use('Agg')
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
def update(i, ln):
i = i+1
x = i
y = i ** 2
x_data = ln.get_xdata()
y_data = ln.get_ydata()
ln.set_data(np.concatenate(([x], x_data)),
np.concatenate(([y], y_data)))
return ln
if __name__ == "__main__":
fig, ax = plt.subplots()
ax.set_xlim(1, 10)
ax.set_ylim(1, 100)
line, = ax.loglog([1], [1])
anim = FuncAnimation(fig, update, frames=np.arange(0, 10), interval=200,
fargs=(line, ))
anim.save('Test.gif', dpi=80, writer='imagemagick')
Works as expected. This makes me think that there is some other error in your code which is getting masked.

Related

Why does matplotlib draw `Title` artists over one another in an animation using `FuncAnimation` (but the same doesn't happen with a `plot`)?

Consider the following animation in python written in a file test.py
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np
fig, ax = plt.subplots()
title = fig.suptitle("Test _")
p, = ax.plot([0,2], [0,1])
def anim(i):
title.set_text("Test %d" % i)
p.set_data([np.random.rand(),i], [np.random.rand(),i])
ani = FuncAnimation(fig, anim, 10, blit=False)
plt.show()
This works as expected when I run it from the command line python test.py and also from an interactive shell: a line segment with changing start and end point is animated.
Now let's set blit=True
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import matplotlib as mpl
import numpy as np
import time
fig, ax = plt.subplots()
p, = ax.plot([0,2], [0,1])
def init_func():
return p,
def anim(i):
p.set_data([np.random.rand(),i], [np.random.rand(),i])
return p,
ani = FuncAnimation(fig, anim, 10, blit=True, init_func=init_func)
plt.show()
This also works both on command line and interactive shell.
However, I would like to animate the title of the plot.
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import matplotlib as mpl
import numpy as np
import time
fig, ax = plt.subplots()
title = ax.set_title("Initial Title")
p, = ax.plot([0,2], [0,1])
def init_func():
return p, title
def anim(i):
title.set_text("3D Test %d" % i)
p.set_data([np.random.rand(),i], [np.random.rand(),i])
return p, title
ani = FuncAnimation(fig, anim, 100, blit=True, init_func=init_func)
plt.show()
This almost works but it two things happen:
in interactive shell, the title stays fixed with "Initial Title". It doesn't update
from the command line, the titles do appear and update but they all overlap each other (there is apparently no erasing previous titles when redrawing the new ones).
As you can see, the plot itself doesn't have this issue.
Why does this happen only with the Title artist?
Finally consider the following variant of this code
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import matplotlib as mpl
import numpy as np
import time
fig, ax = plt.subplots()
title = ax.set_title("50")
p, = ax.plot([0,2], [0,1])
def init_func():
return p,
def anim(i):
title.set_text("3D Test %d" % i)
p.set_data([np.random.rand(),i], [np.random.rand(),i])
return p,
ani = FuncAnimation(fig, anim, 100, blit=True, init_func=init_func)
plt.show()
Here we are calling title.set_text in each update function, but the title artist is not returned so as far as I know FuncAnimation does not consider it as an artist to redraw.
Nonetheless, what happens is that
from the command line the title does get updated but the plot is animated for a few frames and then disappears.
from the interactive shell, the title just stays stuck on the initial title but the plot does work.
What is happening here?

matlibplot real-time plotting doesn't work

I have created the script below for real-time data plotting. But the plot which shows up is empty. Could you tell me what's the case?
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib import style
from itertools import count
import random
style.use('fivethirtyeight')
fig = plt.figure()
axl = fig.add_subplot(1,1,1)
x_vals = []
y_vals = []
index = count()
def animate(i):
x_vals.append(next(index))
y_vals.append(random.randint(0, 5))
axl.clear()
axl.plot(x_vals,y_vals)
ani = animation.FuncAnimation(fig, animate, interval=1000)
plt.show()
I'm using python 3.8, matlibplot 3.1.2 and PyCharm as IDE.

Matplotlib animation not showing any plot

I am trying to make an animation in 3D using Matplotlib and mpl_toolkits. For starter, I am trying to make an animation of a shifting cos wave. But when I run the program, the plot is completely empty. I have just started learning matplotlib animations, so I don't have in-depth knowledge of it. Here is my code:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import math
import matplotlib.animation as animation
fig = plt.figure()
ax = Axes3D(fig)
line, = ax.plot([],[])
print(line)
X = np.linspace(0, 6*math.pi, 100)
def animate(frame):
line.set_data(X-frame, np.cos(X-frame))
return line
anim = animation.FuncAnimation(fig, animate, frames = 100, interval = 50)
plt.show()
Here is the output:
What is wrong with my code? Why am I not getting any output?
There are two issues with your code:
use set_data_3d to update the data of a Line3D object instead of set_data
initialize the Axes3D scales before starting the animation
This should work:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import math
import matplotlib.animation as animation
fig = plt.figure()
ax = Axes3D(fig)
# initialize scales
ax.set_xlim3d(0, 6 * math.pi)
ax.set_ylim3d(-1, 1)
ax.set_zlim3d(0, 100)
X = np.linspace(0, 6 * math.pi, 100)
line, = ax.plot([], [], [])
def animate(frame):
# update Line3D data
line.set_data_3d(X, np.cos(X - frame), frame)
return line,
anim = animation.FuncAnimation(fig, animate, frames = 20, interval = 50)
plt.show()
and yield an animation like this (I have truncated the number of frames to reduce image file size).

Matplotlib animate data in a dataframe using FuncAnimation command in matplotlib

I have data saved in a dataframe format (xarray, similar to Pandas), and I want it to be animated with pcolormesh.
import sys
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
def animate(i):
graph_data = mytest.TMP_P0_L1_GLL0[i]
ax1.pcolormesh(graph_data)
FuncAnimation(plt,animate,frames=100)
which doesn't work for some reason (there is no error but when I show fig it is not animating).
the way the data is laid out is that pcolormesh(mytest.TMP_P0_L1_GLL0[0]) will output a quadmesh, pcolormesh(mytest.TMP_P0_L1_GLL0[1]) will output a slightly different quadmesh...etc
Thanks for your help!
The signature of FuncAnimation is FuncAnimation(fig, func, ...). Instead of the pyplot module you need to supply the figure to animate as first argument.
Further, you need to retain a reference to the animation class, ani = FuncAnimation. The following is a minimal example which works fine.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
class test():
TMP_P0_L1_GLL0 = [np.random.rand(5,5) for i in range(100)]
mytest = test()
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
def animate(i):
graph_data = mytest.TMP_P0_L1_GLL0[i]
ax1.pcolormesh(graph_data)
ani = FuncAnimation(fig,animate,frames=100)
plt.show()

How do I get rid of the static graph from matplotlib.animation?

Here's the code that produces an animation using matplotlib. When I run it in Jupyter notebook, I also get another static graph below the animated graph. How do I remove it?
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from IPython.display import HTML
fig, ax = plt.subplots()
x = np.arange(0, 20, 0.1)
ax.scatter(x, x + np.random.normal(0, 3.0, len(x)))
line, = ax.plot(x, x - 5, 'r-', linewidth=2)
def update(i):
label = 'timestep {0}'.format(i)
line.set_ydata(x - 5 + i)
ax.set_xlabel(label)
return line, ax
anim = FuncAnimation(fig, update, frames=np.arange(0, 10), interval=200)
HTML(anim.to_html5_video())
I use a module called JSAnimation (see this example notebook from the Author).
To display the animation, you simply call:
from JSAnimation.IPython_display import display_animation
display_animation(anim)

Categories