user3771983
user3771983

Reputation: 47

1D animation over time using matplotlib

I have never tried doing animations in python before so apologies in advance is this question seems stupid. I’ve looked around on the forum but struggled to find anyone doing a simulation like I am over time which had an answer I was able to understand.

I have a variable (maxfs) which is a function of time (t). I have calculated h and made a number of 1D plots and I can plot different timesteps as maxfs evolves over time but only by manually changing t. However I am presenting some data in a presentation and for demonstrative purposes I would like to show how the solution evolves over time. My initial thought was to run a for loop for time (t) calculating h at all points (this is what I would do in MATLAB), however looking at the examples in the Matplotlib documentation I am not sure whether carrying out an animation this way is possible. I have included my code below, if anyone has any suggestions on whether my original idea would be a possible way of doing it or whether there’s an alternative method that would be great. I am fairly new to python so ideally I am looking for a fairly simple solution if possible, as I am short on time. Thanks in advance.

__author__="ahe"
__date__ ="$23-Jul-2014$"


import numpy as np
import matplotlib.pyplot as plt 
import math 
import sys
from math import sqrt  
import decimal
from sklearn.metrics import mean_square_error
from matplotlib import gridspec


t=1
l=1
d=0.088
g=9.81
l2=l**2.0

# fs1=FS(0,0)        fs2=FS(xm,0)
fs1=0.04
fs2=0.02
xm=-0.5
omega=((2*g*d)/l2)**0.5
B=g*((fs1-fs2)/(omega*xm))
C=fs1+(g*(((fs1-fs2)**2.0)/(4*omega*(xm**2.0))))


nx, ny = (101,101)
x5 = np.linspace(-2,2,nx)
y5 = np.linspace(-2,2,ny)
xv,yv = np.meshgrid(x5,y5)
x = np.arange(-2,2.04,0.04)
y = np.arange(-2,2.04,0.04)

nx2,ny2 = (111,111)
x10 = np.linspace(-2.2,2.24,nx2)
y10 = np.linspace(-2.2,2.24,ny2)
xv1,yv1 = np.meshgrid(x10,y10)
x1=np.arange(-2.2,2.22,0.04,dtype=float)
y1=np.arange(-2.2,2.22,0.04,dtype=float)
t59=np.arange (1,12321,1,dtype=float)
print len(x1),len(y1)


# Building the parabolic basin (Bottom)
zf=np.arange(len(t59),dtype=float)
zf=   (0.088*((x1[None,:]**2)+(y1[:,None]**2)))-0.2
zf5=np.reshape(zf,(111,111))
zf1 = zf5[55,:]
zf2=zf1[5:106]
# End of building parabolic basin



h=np.zeros(len(x))
eq1=-((((B**2.0)*omega)/(4*g))*math.cos(2*omega*t))+C
term=(B*omega)/g
print 'eq1=',eq1,'term=',term

for i in range(len(x)):
   h[i] = eq1 - ((term*math.cos(omega*t)*x[i]))

maxfs=np.maximum([zf2],[h])
maxfs=maxfs[0]



# PLOTTING
plt.figure(1)
plt.plot(x,maxfs,'r',lw=1.5)
plt.plot(x1,zf1,'k',lw=1.5)
plt.legend(['Analytical','Bathymetry'], loc='upper center',fancybox=True,prop={'size':12})
plt.ylabel('Free Surface [m]',fontsize=12)
plt.xlabel('Distance [m]',fontsize=12)
plt.axis([-2.5,2.5,-0.2,0.25])
plt.title ('Initial conditions for planar surface',fontsize=15)
#plt.text(-0.43,0.30,RMSE,fontsize=12,bbox=props)#,bbox=dict(facecolor='none',edgecolor='black'))
plt.show()

Upvotes: 0

Views: 1197

Answers (1)

Molly
Molly

Reputation: 13610

You could create an animation using a for loop as you suggest and display or save each plot as it is created. You can also use the Matplotlib animation module. This will allow you to save your animation in a format that can be included in a presentation. There animation module lets you define a function that updates the artists at each iteration. In your example that would be updating two lines each time. This basic example does something similar. The tutorial here might also be helpful.

Here is an example that uses simpler math than you included but should give you the idea:

import numpy as np
import matplotlib.pyplot as plt 
import matplotlib.animation as animation


# Set up the figure
fig = plt.figure(1)
# Creat two lines to be updates in the animation. 
l1, = plt.plot([],[],'r',lw=1.5)
l2, = plt.plot([],[],'k',lw=1.5)
plt.legend(['Analytical','Bathymetry'], loc='upper center',fancybox=True,prop={'size':12})
plt.ylabel('Free Surface [m]',fontsize=12)
plt.xlabel('Distance [m]',fontsize=12)
plt.axis([-2.5,2.5,-0.2,0.25])
plt.title ('Initial conditions for planar surface',fontsize=15)

# Initialization function
def init():
    l1.set_data([], [])
    l2.set_data([], [])
    return l1,l2

# This function is called at each iteration of the animation.     
def update(t):
    x = np.arange(-3,3,0.1)
    x1 = np.arange(-3,3,0.1)

    maxfs = 0.1 * np.sin(x * t)
    zf1 = 0.1 * np.cos(x * t)

    # Update lines with new data. 
    l1.set_data(x,maxfs)
    l2.set_data(x1,zf1)
    return l1,l2

# Create animation
ani = animation.FuncAnimation(fig, update, frames = 10, blit=True, init_func = init)

plt.show()

Upvotes: 2

Related Questions