I've been new to python, and recently I am trying with the FuncAnimation recently. I was trying to make a graph that shows the diffusion graphs for every different p and q values, so each time it's supposed to mutate on the current line graph with different p and q as parameters for a fixed amount of t. I've been trying to animate this so that the change with respect to p and q changes on the graph can be seen.
import matplotlib.animation as ani
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import matplotlib.animation as ani
import math
from IPython import display
def eq(p,q,t):
return (1-pow(math.e,-(p q)*t))/(1 q/p*pow(math.e,-(p q)*t))
def diffusion(p,q,t):
d=[]
for i in range(len(t)):
d.append(eq(p,q,t[i]))
return np.array(d)
t=np.linspace(0,20,200)
pq=[]
for i in np.linspace(1,0,20,endpoint=False)[::-11]:
for j in np.linspace(1,0,20,endpoint=False)[::-11]:
pq.append((i,j))
titles = ["Base Diffusion graph (p={}, q={})".format(round(frame[0],2),round(frame[1],2)) for frame in pq]
#print(titles)
fig = plt.figure()
plt.xlabel("t")
plt.ylabel("F(t)")
def buildmechart(i=int):
plt.title(titles[i])
p = plt.plot(t,diffusion(pq[i][0],pq[i][1],t)) #note it only returns
return p,
animator=ani.FuncAnimation(fig,buildmechart,frames=range(len(pq)),interval=100,repeat=False)
animator.save(r'animation.gif')
However, when I run the code above there isn't any animated graph saved, instead on jupyter it only shows a static graph of multiple lines on it. This isn't what I intended; I wanted to change on the current line instead of drawing a new line for each p, q values. So how should I change this code?
Secondly, when I tried to add blit into the FuncAnimation as a parameter, it doesn't seem to allow me add that due to a error
RuntimeError: The animation function must return a sequence of Artist objects. So what should I do?
CodePudding user response:
The problem is that func
argument should be a callable that updates the plot. Currently you plot a new line in your update function. There are some simple examples with good explanation on this page showing how to use the animation feature. Below I slightly modify a few lines of your code to get your desired output.
import matplotlib.animation as ani
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import matplotlib.animation as ani
import math
def eq(p,q,t):
return (1-pow(math.e,-(p q)*t))/(1 q/p*pow(math.e,-(p q)*t))
def diffusion(p,q,t):
d=[]
for i in range(len(t)):
d.append(eq(p,q,t[i]))
return np.array(d)
t=np.linspace(0,20,200)
pq=[]
for i in np.linspace(1,0,20,endpoint=False)[::-11]:
for j in np.linspace(1,0,20,endpoint=False)[::-11]:
pq.append((i,j))
titles = ["Base Diffusion graph (p={}, q={})".format(round(frame[0],2),round(frame[1],2)) for frame in pq]
#print(titles)
fig = plt.figure()
plt.xlabel("t")
plt.ylabel("F(t)")
p, = plt.plot(t,diffusion(pq[0][0],pq[0][1],t)) # Create the line
plt.ylim(-0.05, 1.05) # Making sure the plot fits
def buildmechart(i=int):
plt.title(titles[i])
p.set_data(t,diffusion(pq[i][0],pq[i][1],t)) # Update the line
return p,
animator=ani.FuncAnimation(fig,buildmechart,frames=range(len(pq)),interval=100,repeat=False)
animator.save(r'animation.gif')
plt.show()