将参数图从 mathematica 转换为 python
Convert a parameteric plot from mathematica to python
我有一个小的参数图,我正试图将其从 Mathematica 转换为 python。问题是我的 python 脚本与此不匹配,我正在努力使列表图正常工作,因为它将在 Mathematica 中使用。
你会如何使用 matplotlib 在 python 中编写这个?
With[{r = 2.1, dt = 0.5, tfinal = 7.0},
x = 1;
y = 0;
xylist = {{x, y}};
Do[
x = x - r y dt;
y = y + r x dt;
AppendTo[xylist, {x, y}];
, {i, 0, tfinal, dt}];
p1 = ParametricPlot[{Cos[t], Sin[t]}, {t, 0, 2 \[Pi]},
PlotStyle -> Dashed];
p2 = ListPlot[xylist, Joined -> True, AspectRatio -> 1];
Show[p1, p2, PlotRange -> All]
]
# ========================= Python ========================= #
# Parameters
r = 2.1
tfinal = 7.0
dt = 0.5
n = int(tfinal/dt)
# Containers
tspan = np.linspace(0, tfinal, n)
xtraj = np.zeros(n+1)
ytraj = np.zeros(n+1)
x0 = 1 # Initialize X
y0 = 0 # Initialize Y
value = odeint(f1, [x0,y0],tspan) # ODE values
# Euler scheme to calculate trajectory
# Initialize
xtraj[0] = x0
ytraj[0] = y0
for i in range(n):
xtraj[i+1] = xtraj[i] - r*ytraj[i]*dt
ytraj[i+1] = ytraj[i] + r*xtraj[i]*dt
fig, ax1 = plt.subplots(figsize=(9, 9))
# Plot ODE result portion
plt.plot(xtraj ,ytraj ,label='simulation $\Delta t = 0.1$, $r=1$, $T = 7$ ', color='#96CDCD', marker='o', linestyle='dashed', alpha=0.7)
theta = np.linspace( 0 , 2 * np.pi , 150 )
radius = 1
a = radius * np.cos( theta ) + 0
b = radius * np.sin( theta ) + 0
ax1.plot( a, b , label='actual, r=1', c='k')
ax1.set_aspect( 1 )
ax1.set(xlim=(-1.5, 1.5), ylim=(-1.5, 1.5), );
问题是在您的 Mathematica 中,x
的值在每次迭代时通过“do”循环进行更新。替换
ytraj[i+1] = ytraj[i] + r*xtraj[i]*dt
和
ytraj[i+1] = ytraj[i] + r*xtraj[i+1]*dt
你会看到相同的结果(当然是绘图格式,比如颜色和线型):
请注意,就目前而言,您的 python 是一个正确实施的 Euler 积分器;这是你的 Mathematica 不完全 'Eulerian'(它接近 Euler-Cromer 方法,虽然不完全)
我有一个小的参数图,我正试图将其从 Mathematica 转换为 python。问题是我的 python 脚本与此不匹配,我正在努力使列表图正常工作,因为它将在 Mathematica 中使用。
你会如何使用 matplotlib 在 python 中编写这个?
With[{r = 2.1, dt = 0.5, tfinal = 7.0},
x = 1;
y = 0;
xylist = {{x, y}};
Do[
x = x - r y dt;
y = y + r x dt;
AppendTo[xylist, {x, y}];
, {i, 0, tfinal, dt}];
p1 = ParametricPlot[{Cos[t], Sin[t]}, {t, 0, 2 \[Pi]},
PlotStyle -> Dashed];
p2 = ListPlot[xylist, Joined -> True, AspectRatio -> 1];
Show[p1, p2, PlotRange -> All]
]
# ========================= Python ========================= #
# Parameters
r = 2.1
tfinal = 7.0
dt = 0.5
n = int(tfinal/dt)
# Containers
tspan = np.linspace(0, tfinal, n)
xtraj = np.zeros(n+1)
ytraj = np.zeros(n+1)
x0 = 1 # Initialize X
y0 = 0 # Initialize Y
value = odeint(f1, [x0,y0],tspan) # ODE values
# Euler scheme to calculate trajectory
# Initialize
xtraj[0] = x0
ytraj[0] = y0
for i in range(n):
xtraj[i+1] = xtraj[i] - r*ytraj[i]*dt
ytraj[i+1] = ytraj[i] + r*xtraj[i]*dt
fig, ax1 = plt.subplots(figsize=(9, 9))
# Plot ODE result portion
plt.plot(xtraj ,ytraj ,label='simulation $\Delta t = 0.1$, $r=1$, $T = 7$ ', color='#96CDCD', marker='o', linestyle='dashed', alpha=0.7)
theta = np.linspace( 0 , 2 * np.pi , 150 )
radius = 1
a = radius * np.cos( theta ) + 0
b = radius * np.sin( theta ) + 0
ax1.plot( a, b , label='actual, r=1', c='k')
ax1.set_aspect( 1 )
ax1.set(xlim=(-1.5, 1.5), ylim=(-1.5, 1.5), );
问题是在您的 Mathematica 中,x
的值在每次迭代时通过“do”循环进行更新。替换
ytraj[i+1] = ytraj[i] + r*xtraj[i]*dt
和
ytraj[i+1] = ytraj[i] + r*xtraj[i+1]*dt
你会看到相同的结果(当然是绘图格式,比如颜色和线型):
请注意,就目前而言,您的 python 是一个正确实施的 Euler 积分器;这是你的 Mathematica 不完全 'Eulerian'(它接近 Euler-Cromer 方法,虽然不完全)