Matplotlib FuncAnimation not animating line plot - python-3.x

I have two random vectors which are used to create a line plot. Using the same vectors, I would like to animate the line but the animation is static - it just plot the original graph. Any suggestions on how to animate such a line plot?
import numpy as np
import matplotlib.pyplot as py
from matplotlib import animation
# random line plot example
x = np.random.rand(10)
y = np.random.rand(10)
py.figure(3)
py.plot(x, y, lw=2)
py.show()
# animation line plot example
fig = py.figure(4)
ax = py.axes(xlim=(0, 1), ylim=(0, 1))
line, = ax.plot([], [], lw=2)
def init():
line.set_data([], [])
return line,
def animate(i):
line.set_data(x, y)
return line,
anim = animation.FuncAnimation(fig, animate, init_func=init, frames=200, interval=20, blit=False)
The final frame of the animation should look something like the plot below. Keep in mind that this is a random plot so the actual figure will change with each run.

Okay, I think what you want is to only plot up to the i-th index for frame i of the animation. In that case, you can just use the frame number to limit the data displayed:
import numpy as np
import matplotlib.pyplot as py
from matplotlib import animation
x = np.random.rand(10)
y = np.random.rand(10)
# animation line plot example
fig = py.figure(4)
ax = py.axes(xlim=(0, 1), ylim=(0, 1))
line, = ax.plot([], [], lw=2)
def init():
line.set_data([], [])
return line,
def animate(i):
line.set_data(x[:i], y[:i])
return line,
anim = animation.FuncAnimation(fig, animate, init_func=init, frames=len(x)+1,
interval=200, blit=False)
Notice I changed the number of frames to len(x)+1 and increased the interval so it's slow enough to see.

Related

How to update scatter with plot?

I am updating the graph, but can't join to it the scatter, could someone help me, please? I don't understand, how to realize it.
from matplotlib import pyplot as plt
from matplotlib.animation import FuncAnimation
fig = plt.figure()
ax = fig.add_subplot()
line = ax.plot([],[])[0]
x = []
y = []
scat = ax.scatter(x,y,c='Red')
def animate(i):
x.append(i)
y.append((-1)**i)
line.set_data(x, y)
ax.relim()
ax.autoscale_view()
return [line]
anim = FuncAnimation(fig, animate, frames=200, interval=100, blit=True)
plt.show()
I want to add dotes and their coordinates change only in X, Y should be 0.
Several problems have to be addressed here. You have to update the scatter plot, which is a PathCollection that is updated via .set_offsets(). This is in turn requires the x-y data to be in an array of the form (N, 2). We could combine the two lists x, y in every animation loop to such an array but this would be time-consuming. Instead, we declare the numpy array in advance and update it in the loop.
As for axes labels, you might have noticed that they are not updated in your animation. The reason for this is that you use blitting, which suppresses redrawing all artists that are considered unchanged. So, if you don't want to take care manually of the axis limits, you have to turn off blitting.
from matplotlib import pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np
fig, ax = plt.subplots()
line, = ax.plot([],[])
scat = ax.scatter([], [], c='Red')
n=200
#prepare array for data storage
pos = np.zeros((n, 2))
def animate(i):
#calculate new x- and y-values
pos[i, 0] = i
pos[i, 1] = (-1)**i
#update line data
line.set_data(pos[:i, 0], pos[:i, 1])
#update scatter plot data
scat.set_offsets(pos[:i, :])
#update axis view - works only if blit is False
ax.relim()
ax.autoscale_view()
return scat, line
anim = FuncAnimation(fig, animate, frames=n, interval=100, blit=False)
plt.show()
Sample output:

Line on animated matplotlib graph not showing up

I'm not sure why a graph line isn't showing on my widget.
The x-axis is moving with time as it should, and when I print the y-values that should be plotted (Temp), new values come up as expected. However, no line/points show up on the plot.
I've had a similar issue with a plot in the past, which was solved by changing the style of the points plotted (i.e. using 'r*' to make the points visible red stars). I'm not sure how to implement the same sort of thing in this code.
import matplotlib.pyplot as plt
import numpy
import datetime
import matplotlib.animation as animation
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
def animate(i):
Time = []
Temp = []
x = datetime.datetime.now()
y = numpy.random.randint(48,52)
Time.append(x)
Temp.append(int(y))
ax1.plot(Time,Temp)
print(Temp)
ani = animation.FuncAnimation(fig,animate, interval=1000)
plt.show()
just put Time and Temp out of function animate
Time = []
Temp = []
def animate(i):
x = datetime.datetime.now()
y = numpy.random.randint(48,52)
Time.append(x)
Temp.append(int(y))
ax1.plot(Time,Temp)
print(Temp)
You can add the marker and it shows the points:
ax1.plot(Time,Temp, marker="s")

matplotlib animation with multiple plots and for loop

hey I'm trying to get matplotlib.animation to plot n plots in one graph like the first code block below, but when I run the script everything seems to run except none of the plots show up.
import matplotlib.pyplot as plt
# Data to be ploted
x = []
y = []
x2 = []
y2 = []
for i in range(-9,9):
x.append(i)
y.append(i**2)
x2.append(i)
y2.append(i**3)
# plot the data
plt.plot(x,y, label = 'first line')
# plot other data points
plt.plot(x2,y2, label = 'second line')
# add this before plt.show() to add labels to graph
plt.xlabel('X value')
plt.ylabel('Y value')
# add a title to graph
plt.title('interesting graph\nsubtitle')
plt.legend()
plt.show()
here is the code using animate:
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib import style
# better face
style.use('fivethirtyeight')
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
def anima(i):
graph_data = open('a.txt').read()
lines = graph_data.split('\n')
dataPoints = []
for i in lines:
# ignor empty lines
if len(i) > 1:
line = i.split('|') # delimiter is |
for a in range(len(line)):
try:
dataPoints[a].append(int(line[a]))
# if there is no dataPoint[a] it gets created
except:
dataPoints.append(int(line[a]))
# modify axis
ax1.clear()
# plot
for i in range(len(dataPoints)-1):
ax1.plot(dataPoints[1],dataPoints[i+1])
#where to animate, what to animate, how often to update
ani = animation.FuncAnimation(fig, anima, interval = 1000)
plt.show()
in a.txt I have this:
1|56|80|62
2|123|135|55
12|41|12|23
60|12|45|23
12|43|56|54
25|123|23|31
2|213|31|84
61|1|68|54
62|2|87|31
63|4|31|53
64|8|13|13
65|16|51|65
66|32|43|84
80|62|42|15
update:
I gave up on reading a file and am having a threaded function generate values for me and instead for having everything in one plot I am having everything in subplots(the number is going to be edited soon). when I run the code with a normal plot it works fine, but when I try to use animate... it shows the graphs but no plot once again. my problem is showing the animated plot
# check if os is linux
import platform
if str(platform.system()).lower() == str('linux').lower():
# must be set befor importing any other matplotlib
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib import style
from threading import Thread
# Change style
style.use('fivethirtyeight')
fig = plt.figure()
#list with all datapoints eg: [timeList],[graph1List]....
data_points = []
# 'name' of each graph in the list
graphs_ = [0]
def create_plots():
xs = []
ys = []
for i in range(-10,11):
x = i
y = i**3
xs.append(x)
ys.append(y)
data_points.append(xs)
data_points.append(ys)
t = Thread(target=create_plots)
t.start()
def anima(i):
for i in range(len(graphs_)):
graphs_[i]=fig.add_subplot(211+i)
graphs_[i].clear()
graphs_[i].plot(0,i+1)
while len(data_points) == 0:
print('.')
ani = animation.FuncAnimation(fig, anima, interval=1000)
plt.show()
1) Are you sure your anima(i) function gets called?
2) Why are you overwriting the variable i in anima(i) and again in line?
for i in lines:
# ignor empty lines

How to do Cartopy simple animations

I am trying to create a simple animation using Cartopy. Basically just drawing a few lines in the map. So far I am trying the following:
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import matplotlib.animation as animation
import numpy as np
ax = plt.axes(projection=ccrs.Robinson())
ax.set_global()
ax.coastlines()
lons = 10 * np.arange(1, 10)
lats = 10 * np.arange(1, 10)
def animate(i):
plt.plot([lons[i-1], lons[i]], [lats[i-1], lats[i]], color='blue', transform=ccrs.PlateCarree())
return plt
anim = animation.FuncAnimation(plt.gcf(), animate, frames=np.arange(1, 8), init_func=None, interval=2000, blit=True)
plt.show()
Does anyone know why this is not working?
This is unrelated to cartopy, I would guess. The problem is that you cannot return pyplot from the animation function. (It's like instead of buying a book, you'd buy the whole book store and then wonder why you can't read a book store.)
The easiest solution is to turn blitting off:
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
fig, ax = plt.subplots()
lons = 10 * np.arange(1, 10)
lats = 10 * np.arange(1, 10)
def animate(i):
plt.plot([lons[i-1], lons[i]], [lats[i-1], lats[i]], color='blue')
anim = animation.FuncAnimation(plt.gcf(), animate, frames=np.arange(1, 8),
init_func=None, interval=200, blit=False)
plt.show()
If for some reason you need blitting (which would the case if the animation is too slow or consumes too much CPU), you need to return a list of the Line2D objects you want to draw.
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
fig, ax = plt.subplots()
lons = 10 * np.arange(1, 10)
lats = 10 * np.arange(1, 10)
lines = []
def animate(i):
line, = plt.plot([lons[i-1], lons[i]], [lats[i-1], lats[i]])
lines.append(line)
return lines
anim = animation.FuncAnimation(plt.gcf(), animate, frames=np.arange(1, 8),
interval=200, blit=True, repeat=False)
plt.xlim(0,100) #<- remove when using cartopy
plt.ylim(0,100)
plt.show()
The Warining is
The animation function must return a sequence of Artist objects
So just change the blit keyword from True to false and then save the animation into a gif file can solve this.
Otherwise, you can plot a sequence of Artist objects can then set the
blit=True as follows:
ax = plt.axes(projection=ccrs.Robinson())
ax.set_global()
ax.coastlines()
lons = 10 * np.arange(1, 10)
lats = 10 * np.arange(1, 10)
def animate(i):
line = ax.plot([lons[i-1], lons[i]], [lats[i-1], lats[i]], color='blue', transform=ccrs.PlateCarree())
return line
anim = animation.FuncAnimation(plt.gcf(), animate, frames=np.arange(1, 8), init_func=None, interval=200, blit=True)
anim.save('test.gif')
plt.show()
May these help you.

Python: Matplotlib: update graph by time in second

I have a series to plot at y-axis.
y = [3,4,5,1,4,7,4,7,1,9]
However, I want to plot it by recent time by second. I've done it like this,
import time
def xtime():
t = time.strftime("%H%M%S")
t = int(t)
xtime = [t]
while xtime:
t = time.strftime("%H%M%S")
t = int(t)
xtime.extend([t])
time.sleep(1)
I'm having problem when I want to plot each one of the number at y by each second. Please correct my code here,
import time
import matplotlib.pyplot as plt
import matplotlib.animation as animation
fig = plt.figure()
def animate(i):
x = xtime()
y = [3,4,5,1,4,7,4,7,1,9]
plt.plot(x,y)
ani = animation.FuncAnimation(fig, animate, interval=1000)
plt.show()
xtime function is referred as code at first.
Thanks!
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
# Y data
ydata = [3,4,5,1,4,7,4,7,1,9]
# how many points
N = len(ydata)
# make x data
xdata = np.arange(N)
def animate(i):
# update the date in our Line2D artist
# note that when run this will look at the global namespace for
# an object called `ln` which we will define later
ln.set_data(xdata[:i], ydata[:i])
# return the updated artist for the blitting
return ln,
# make our figure and axes
fig, ax = plt.subplots()
# make the artist we will be using. Note this was used in `animate`
ln, = ax.plot([], [], animated=True)
# set the axes limits
ax.set_xlim(0, N)
ax.set_ylim(0, 10)
# run the animation. Keeping a ref to the animation object is important
# as if it gets garbage collected it takes you timer and callbacks with it
ani = animation.FuncAnimation(fig, animate, frames=N, interval=1000, blit=True)

Resources