简体   繁体   中英

Interactive continuous plotting of an ODE model in Python

I would like to create a script that integrates an ode model, such that I can change one of the parameters and see the response of the systems to this change. If for, for example, I have a Lotka-Volterra model (as taken from this 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)

I would like to create a slider for parameters a and c , as in the slider_demo of matplotlib , or any other tool. The plot should display a certain window of time that always spans [t_current - delta_t ,t_current] . And so I will be able to explore the parameters space continuously by changing the sliders of the parameters.

How to do it?

You have all the pieces, basically just change the update method in the widget example to recalculate the integral of dX_dt using the new value based on the sliders and then use this to set the y line values. The code would look like:

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()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM