Dah_Fisicist
Dah_Fisicist

Reputation: 25

How do I make a plot that changes through time?

Now, here is the code I'm working with:

import numpy                       
from matplotlib import pyplot as plt     
import time, sys                   

nx = 41  
dx = 2 / (nx-1)
nt = 25    
dt = 0.025
c = 1      
fig = plt.figure()

u = numpy.ones(nx)    
u[int(.5 / dx):int(1 / dx + 1)] = 2  
print(u)


un = numpy.ones(nx)

for n in range(nt):
    un = u.copy()
    plt.plot(numpy.linspace(0, 2, nx), u)
    for i in range(1, nx):
        u[i] = un[i] - c*dt/dx * (un[i] - un[i - 1])

plt.show()

It should animate the solution to the equation ∂u/∂t + c * ∂u/∂x = 0; but I don't know how to animate it - because at the current state, it shows at once the function at all time steps; and if instead I put plt.show() inside the loop (the outer one), it shows the graphs one at a time, and I have to close the graph window to see the next, which is not very convenient.

Upvotes: 1

Views: 215

Answers (2)

JohanC
JohanC

Reputation: 80359

FuncAnimation can be used to create animations.

The code of the post can be rendered as an animation as follows:

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

nx = 41
dx = 2 / (nx-1)
nt = 25
dt = 0.025
c = 1
fig = plt.figure()

u = np.ones(nx)
u[int(.5 / dx):int(1 / dx + 1)] = 2

x = np.linspace(0, 2, nx)

plot1, = plt.plot(x, u)

def update(t):
    un = u.copy()
    for i in range(1, nx):
        u[i] = un[i] - c*dt/dx * (un[i] - un[i - 1])
    plot1.set_ydata(u)
    return plot1,

FuncAnimation(fig, update, frames=nt, blit=True)
plt.show()

PS: Note the comma after plot1 in plot1, = plt.plot(.... This grabs the first element in the list returned by plt.plot.

Upvotes: 1

j-m-dean
j-m-dean

Reputation: 36

You could save it as a gif using the following:

import numpy                       
from matplotlib import pyplot as plt     
import time, sys   
from celluloid import Camera
from IPython.display import Image

nx = 41  
dx = 2 / (nx-1)
nt = 25    
dt = 0.025
c = 1      
fig = plt.figure()

u = numpy.ones(nx)    
u[int(.5 / dx):int(1 / dx + 1)] = 2  
print(u)


un = numpy.ones(nx)
fig = plt.figure()
camera = Camera(fig)
for n in range(nt):
    un = u.copy()
    plt.plot(numpy.linspace(0, 2, nx), u, color= "blue")
    for i in range(1, nx):
        u[i] = un[i] - c*dt/dx * (un[i] - un[i - 1])
    camera.snap()

animation = camera.animate()
animation.save('solution.gif', writer = 'imagemagick')

In essence it recursively takes a camera "snap" for each dt and collates them into a gif saved as "solution.gif" in the current working directory.

Upvotes: 0

Related Questions