Python - 动画波动方程的数值解

时间:2015-07-09 15:37:25

标签: python animation matplotlib

我正在尝试为波动方程设置解决方案的动画 - 我正在绘制压力和x的位移,但我希望它随着时间的推移而发展。

认为解决方案是将每个位置x视为单个“粒子”,然后让粒子服从定义y的函数,并在t中激活它?然而,我看到实现这一点的唯一方法似乎有点过于暴力,导致笨重的代码应该真正简短。

我打算扩展这段代码以允许mu和rho成为依赖于位置而不是常量的变量,但是现在我只想让动画工作。

代码:

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

# Definition of parameters
dt = 0.04
t = np.arange(0.0,40,dt)
x = np.linspace(0, 15, 1000) # x position
Y0 = np.array([0,10])       # initial conditions
mu = 1.5
rho = 1.2
omega = 1
def dY_dx(Y, t=0):
    """ Return the gradient of y1 and y2"""
    return np.array([Y[1] / mu, - (omega ** 2) * rho * Y[0]])

from scipy import integrate

Y = integrate.odeint(dY_dx, Y0, x)

y1, y2 = Y.T

# set up the figure, the axis, and the plot element we want to animate
fig = plt.figure()
ax = fig.add_subplot(111, autoscale_on=False, xlim=(0,15), ylim=(-10,10))
ax.grid()

line1, = ax.plot([], [], 'o', ms=2)
line2, = ax.plot([], [], '-', lw=2)
time_template = 'time = %.lfs'
time_text = ax.text(0.05, 0.9, '', transform=ax.transAxes)

# initialisation function: plot the background of each frame
def init():
    line1.set_data([], [])
    line2.set_data([], [])
    time_text.set_text('')
    return line1, line2, time_text

# animation function: this is called sequentially
def animate(i):

    line1.set_data(x, y1)
    line2.set_data(x, y2)

    time_text.set_text(time_template%(i*dt))
    return line1, line2, time_text

# call the animator. blit=True means only re-draw the parts that have changed
ani = animation.FuncAnimation(fig, animate, np.arange(1, len(Y)), interval=25, blit=True, init_func=init)

#ani.save('waveEquation.mp4', fps=15)
plt.show()

我试过了:

# animation function: this is called sequentially
def animate(i):

    line1.set_data(x[i], y1[i])

# animation function: this is called sequentially
def animate(i):

    line1.set_data(x, y1[i])

但是没有给出我想要的结果。

问题可能是我在绘制之前将我的解决方案整合到t上,然后在动画中不包括t作为变量吗?

我知道我可以使用代码(在这里找到类似的问题):

def animate(i):
    thisx = x
    thisy = np.sin(2 * np.pi * (x - 0.01 * i))

    line1.set_data(thisx, thisy)

动画一个sin波,但我不想使用解析解来计算y,我想用数字来做(以后的问题)。

1 个答案:

答案 0 :(得分:4)

ConorB,

你问:

  

问题可能是我之前在t上整合了我的解决方案   它们被绘制,然后不包括t作为我的变量   动画?

是的,这正是你的问题。 animate定义应该包括t的更新,然后 - 可能 - 需要重新整合并重新计算要绘制的行y1y2。如果不了解一般问题域,很难确切地知道你想让你的情节显示什么,但你的animate函数看起来应该是这样的:

def animate(i):
    t = np.arange(0.0,40,dt) + i*dt
    Y = integrate.odeint(dY_dx,Y0,t)
    y1,y2 = Y.T

    line1.set_data(x, y1)
    line2.set_data(x, y2)

    time_text.set_text(time_template%t)
    return line1, line2, time_text

此外,由于array而不是np.array的调用以及一些错误的空格,您的代码将无法运行。我清理了它,等待同行评审。