我有一些代码可以正确绘制我想要的矢量场。现在,我想绘制一个矢量域中的一个(或几个)粒子的运动并对其进行最终动画处理。现在,我知道我需要与odeint集成以获取放置在网格中的粒子的位置,但是我发现的任何教程或代码段都假设我想绘制与时间相关的参数...现在,我猜我可以分别计算x和y并绘制它们,但是必须有一种更有效的方法吗?我是否要计算向量乘积(u * v)并据此进行绘制?我猜不是。实际上,我正在为odeint所需的参数苦苦挣扎。因此,假设我要以dt = 0.5的时间间隔绘制一个粒子的运动,该粒子的初始位置为X = 0.5和Y = 0.5。
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
from scipy.integrate import odeint
def velocity_field(x, y, t):
vx = -np.sin(2 * np.pi * x) * np.cos(2 * np.pi * y) - 0.1 * np.cos(2 * np.pi * t) * np.sin(
2 * np.pi * (x - 0.25)) * np.cos(2 * np.pi * (y - 0.25))
vy = np.cos(2 * np.pi * x) * np.sin(2 * np.pi * y) + 0.1 * np.cos(2 * np.pi * t) * np.cos(
2 * np.pi * (x - 0.25)) * np.sin(
2 * np.pi * (y - 0.25))
return vx, vy
def entire_domain():
xrange = (0, 1)
yrange = (0, 1)
mesh_sz_x = 50
mesh_sz_y = 50
dx = (xrange[1] - xrange[0]) / (mesh_sz_x - 1)
dy = (yrange[1] - yrange[0]) / (mesh_sz_y - 1)
x_mat, y_mat = np.mgrid[xrange[0]:xrange[1]:dx, yrange[0]:yrange[1]:dy]
x_dot, y_dot = velocity_field(x=x_mat, y=y_mat, t=0)
speed = np.sqrt(x_dot ** 2 + y_dot ** 2)
u_n = x_dot / speed
v_n = y_dot / speed
plt.contourf(x_mat, y_mat, speed, 12, cmap=plt.get_cmap('viridis'),
interp='bicubic')
plt.quiver(x_mat, y_mat, u_n, v_n # data
, color='black'
, headlength=7
, pivot='mid'
,
) # length of the arrows
#This part is wrong
'''
x0 = ?????
y0 = ?????
t = np.arange(0, 100, 0.05)
X = odeint(velocity_field, x0, y0, t)
print(X)
'''
plt.show()
if __name__ == '__main__':
entire_domain()
我试图使用各种数据来整理代码,至少给我一些东西,但是我在数据的odeint行中遇到了常见的错误,因此我只将x0和y0留为空白,因为我怀疑错误在那里。如有其他错误,请随时更正剩余的代码。
此外,我将如何绘制例如5个粒子的路径,将5个不同的初始条件设置为偶,矩阵,然后将它们键入?
谢谢您的时间!
答案 0 :(得分:2)
此处是代码的一部分,并进行了一些修改,以使odeint
正常工作。
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint
def velocity_field(xy, t):
x, y = xy
vx = -np.sin(2*np.pi * x) * np.cos(2*np.pi * y) \
- 0.1*np.cos(2 * np.pi * t) * np.sin(2*np.pi*(x - 0.25)) * np.cos(2*np.pi*(y - 0.25))
vy = np.cos(2*np.pi * x) * np.sin(2*np.pi * y) \
+ 0.1*np.cos(2*np.pi * t) * np.cos(2*np.pi*(x - 0.25)) * np.sin(2*np.pi*(y - 0.25))
return (vx, vy)
xy0 = (0, 0)
t_span = np.arange(0, 100, 0.05)
sol = odeint(velocity_field, xy0, t_span)
plt.plot(sol[:, 0], sol[:, 1]);
plt.axis('equal'); plt.xlabel('x'); plt.ylabel('y');
初始状态 y0
必须是向量(即1d数组),并且y
函数的dy/dt = velocity_field
自变量也必须是向量。因此,x
和y
必须打包在一起,然后在函数中解压缩。
对于具有不同初始条件的多个解决方案,一个简单的解决方案是将求解部分与图混合:(如果计算时间较长,可以将两者分开,例如,通过将解决方案存储在列表中可能会更好,并为绘图使用另一个循环)
initial_conditons = [(1, .4), (1, 0), (4, .7)]
t_span = np.arange(0, 100, 0.05)
plt.figure(figsize=(6, 6))
for xy0 in initial_conditons:
sol = odeint(velocity_field, xy0, t_span)
plt.plot(sol[:, 0], sol[:, 1]);
plt.axis('equal'); plt.xlabel('x'); plt.ylabel('y');
给出: