Medulla Oblongata
Medulla Oblongata

Reputation: 3963

Python simulation not working

I'm creating a Python simulation that models water particles in a gravity wave. So far my code is

import numpy as np
#import matplotlib
import matplotlib.pyplot as plt
#import pylab

#pylab.ion()

h = 2     # water depth
D = 0.4   # wave amplitude
k = 1     # wave number

ds = 0.5
x = np.arange(0, 15+ds, ds)
y = np.arange(0, h+ds, ds)
g = 10
w = np.sqrt(g*k*np.tanh(k*h))
T = 2*np.pi/w
xx,yy = np.meshgrid(x,y)
hp = plt.plot(xx[:],yy[:],'x')
plt.axis('equal')
plt.axis([0,15,0,8]) #axis equal
N = 24

#matplotlib.interactive(True)

t = 0
while (True):
    t = t + T/N
    dispx = D/np.sinh(k*h) * np.outer(np.cosh(k*y), np.cos(k*x-w*t))
    dispy = D/np.sinh(k*h) * np.outer(np.sinh(k*y), np.sin(k*x-w*t))
    plt.setp(hp,'XData',xx[:]+dispx[:], 'YData',yy[:]+dispy[:])
    plt.drawNow()

I simply get a static image, and I know that I'm close. What else should I add to get everything moving? Preferably real-time plotting.

Upvotes: 0

Views: 371

Answers (2)

physicsmichael
physicsmichael

Reputation: 4963

I was able to get 15 fps on my laptop by adding plt.ion() just after importing pyplot and changing plt.drawNow() to plt.draw(). That second step was because I don't have a drawNow method in pyplot.

Upvotes: 0

HYRY
HYRY

Reputation: 97331

You can use timer callback:

import numpy as np
import matplotlib.pyplot as plt

h = 2     # water depth
D = 0.4   # wave amplitude
k = 1     # wave number

ds = 0.5
x = np.arange(0, 15+ds, ds)
y = np.arange(0, h+ds, ds)
g = 10
w = np.sqrt(g*k*np.tanh(k*h))
T = 2*np.pi/w
xx,yy = np.meshgrid(x,y)
hp = plt.plot(xx[:],yy[:],'x')
plt.axis('equal')
plt.axis([0,15,0,8]) #axis equal
N = 24

fig = plt.gcf()

def update():
    t = 0
    while (True):
        t = t + T/N
        dispx = D/np.sinh(k*h) * np.outer(np.cosh(k*y), np.cos(k*x-w*t))
        dispy = D/np.sinh(k*h) * np.outer(np.sinh(k*y), np.sin(k*x-w*t))
        plt.setp(hp,'XData',xx[:]+dispx[:], 'YData',yy[:]+dispy[:])
        fig.canvas.draw_idle()
        yield

timer = fig.canvas.new_timer(interval=10)
timer.add_callback(update().next)
timer.start()

plt.show()

Upvotes: 2

Related Questions