Python 中 ODE 模型的交互式连续绘图
Interactive continuous plotting of an ODE model in Python
我想创建一个集成 ode 模型的脚本,这样我就可以更改其中一个参数并查看系统对此更改的响应。例如,如果我有一个 Lotka-Volterra 模型(取自此 example):
import numpy as np
from scipy import integrate
a = 1.
b = 0.1
c = 1.5
d = 0.75
def dX_dt(X, t=0):
""" Return the growth rate of fox and rabbit populations. """
return array([ a*X[0] - b*X[0]*X[1] ,
-c*X[1] + d*b*X[0]*X[1] ])
t = np.linspace(0, 15, 1000) # time
X0 = np.array([10, 5]) # initials conditions: 10 rabbits and 5 foxes
X, infodict = integrate.odeint(dX_dt, X0, t, full_output=True)
我想为参数 a
和 c
创建一个滑块,就像在 slider_demo of matplotlib 或任何其他工具中一样。该图应显示某个 window 的时间,该时间始终跨越 [t_current - delta_t ,t_current]
。因此,我将能够通过更改参数的滑块来不断探索参数 space。
怎么做?
你有所有的部分,基本上只需更改小部件中的更新方法 example 以使用基于滑块的新值重新计算 dX_dt 的积分,然后使用它来设置y 线值。代码如下所示:
import numpy as np
from scipy import integrate
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons
b = 0.1
d = 0.75
a=1
c=1.5
def dX_dt(X, t=0, a=1, c=1.5):
""" Return the growth rate of fox and rabbit populations. """
return np.array([ a*X[0] - b*X[0]*X[1] ,
-c*X[1] + d*b*X[0]*X[1] ])
t = np.linspace(0, 15, 1000) # time
X0 = np.array([10, 5]) # initials conditions: 10 rabbits and 5 foxes
fig, ax = plt.subplots()
plt.subplots_adjust(left=0.25, bottom=0.25)
l1, l2 = plt.plot(t, integrate.odeint(dX_dt, X0, t, (a, c)))
axcolor = 'black'
ax_a = plt.axes([0.25, 0.1, 0.65, 0.03], axisbg=axcolor)
ax_c = plt.axes([0.25, 0.15, 0.65, 0.03], axisbg=axcolor)
sa = Slider(ax_a, 'a', 0.1, 10.0, valinit=1)
sc = Slider(ax_c, 'c', 0.1, 10.0, valinit=1.5)
def update(val):
a = sa.val
c = sc.val
x = integrate.odeint(dX_dt, X0, t, (a, c))
l1.set_ydata(x[:,0])
l2.set_ydata(x[:,1])
fig.canvas.draw_idle()
sa.on_changed(update)
sc.on_changed(update)
plt.show()
我想创建一个集成 ode 模型的脚本,这样我就可以更改其中一个参数并查看系统对此更改的响应。例如,如果我有一个 Lotka-Volterra 模型(取自此 example):
import numpy as np
from scipy import integrate
a = 1.
b = 0.1
c = 1.5
d = 0.75
def dX_dt(X, t=0):
""" Return the growth rate of fox and rabbit populations. """
return array([ a*X[0] - b*X[0]*X[1] ,
-c*X[1] + d*b*X[0]*X[1] ])
t = np.linspace(0, 15, 1000) # time
X0 = np.array([10, 5]) # initials conditions: 10 rabbits and 5 foxes
X, infodict = integrate.odeint(dX_dt, X0, t, full_output=True)
我想为参数 a
和 c
创建一个滑块,就像在 slider_demo of matplotlib 或任何其他工具中一样。该图应显示某个 window 的时间,该时间始终跨越 [t_current - delta_t ,t_current]
。因此,我将能够通过更改参数的滑块来不断探索参数 space。
怎么做?
你有所有的部分,基本上只需更改小部件中的更新方法 example 以使用基于滑块的新值重新计算 dX_dt 的积分,然后使用它来设置y 线值。代码如下所示:
import numpy as np
from scipy import integrate
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button, RadioButtons
b = 0.1
d = 0.75
a=1
c=1.5
def dX_dt(X, t=0, a=1, c=1.5):
""" Return the growth rate of fox and rabbit populations. """
return np.array([ a*X[0] - b*X[0]*X[1] ,
-c*X[1] + d*b*X[0]*X[1] ])
t = np.linspace(0, 15, 1000) # time
X0 = np.array([10, 5]) # initials conditions: 10 rabbits and 5 foxes
fig, ax = plt.subplots()
plt.subplots_adjust(left=0.25, bottom=0.25)
l1, l2 = plt.plot(t, integrate.odeint(dX_dt, X0, t, (a, c)))
axcolor = 'black'
ax_a = plt.axes([0.25, 0.1, 0.65, 0.03], axisbg=axcolor)
ax_c = plt.axes([0.25, 0.15, 0.65, 0.03], axisbg=axcolor)
sa = Slider(ax_a, 'a', 0.1, 10.0, valinit=1)
sc = Slider(ax_c, 'c', 0.1, 10.0, valinit=1.5)
def update(val):
a = sa.val
c = sc.val
x = integrate.odeint(dX_dt, X0, t, (a, c))
l1.set_ydata(x[:,0])
l2.set_ydata(x[:,1])
fig.canvas.draw_idle()
sa.on_changed(update)
sc.on_changed(update)
plt.show()