1

I'm using Python to plot the system of differential equations

dldt = a*l - b*l*p
dpdt = -c*p + d*l*p

in Jupyter Notebook. How do I add interactive sliders to the plot to allow adjustment of constant parameters in the differential equations?

I've tried adding interactive sliders as per this Jupyter Notebook: https://ipywidgets.readthedocs.io/en/stable/examples/Lorenz%20Differential%20Equations.html, but not being familiar with solving and plotting differential equations in Python, I don't know how to modify it to be able to interact with the parameters a, b, c, and d. The best I could get was a static plot per the code below.

from scipy.integrate import odeint
import matplotlib.pyplot as plt
from IPython.html.widgets import *
import ipywidgets as wg
from IPython.display import display 
from numpy import pi

def f(s, t):

    a = 1
    b = 1
    c = 1
    d = 0.5
    l = s[0]
    p = s[1]
    dldt = a*l - b*l*p
    dpdt = -c*p + d*l*p
    return [dldt, dpdt]

t = np.arange(0,10*pi,0.01)
s0=[0.1,5]

s = odeint(f, s0, t)

plt.plot(t,s[:,0],'r-', linewidth=2.0)
plt.plot(t,s[:,1],'b-', linewidth=2.0)
plt.xlabel("day in menstrual cycle")
plt.ylabel("concentration (ng/mL)")
plt.legend(["LH","P"])
plt.show()

What I desire is a graph that starts out like the static graph, but also has sliders for parameters a, b, c, and d that allows you to change the graph as you change their values.

Susan
  • 13
  • 5

1 Answers1

1

You need a function that takes the parameters of the ODE and additional parameters for the plot as named parameters. In the most simple case just a,b,c,d. This function needs to produce a plot.

def plot_solution(a=1.,b=1.,c=1.,d=0.5):
    def f(s, t):

        l, p = s
        dldt = a*l - b*l*p
        dpdt = -c*p + d*l*p
        return [dldt, dpdt]

    t = np.arange(0,10*np.pi,0.01)
    s0=[0.1,5]

    s = odeint(f, s0, t)

    plt.plot(t,s[:,0],'r-', linewidth=2.0)
    plt.plot(t,s[:,1],'b-', linewidth=2.0)
    plt.xlabel("day in menstrual cycle")
    plt.ylabel("concentration (ng/mL)")
    plt.legend(["LH","P"])
    plt.show()

Then call the interactive widget function as explained in the documentation. Sliders are generated for named parameters that are given pairs of numbers as input.

w = interactive(plot_solution, a=(-2.0,2.0), b=(-2.0,2.0), c=(-2.0,2.0), d=(-2.0,2.0))
display(w)
Lutz Lehmann
  • 25,219
  • 2
  • 22
  • 51
  • I tried this but it doesn't show the sliders in my plot. In jupyter it is working though.... – Jailbone Apr 08 '20 at 22:57
  • 1
    @Jailbone : Yes, this uses IPython/Jupyter widgets. It relays on functionality that the kernel of these programs provides, it uses html/javascript objects. Otherwise use the sliders that matplotlib provides, like inhttps://stackoverflow.com/q/60925986/3088138. This works well standalone but not always that well with jupyter in the browser (as the Qt library of the konqueror browser and the one of matplotlib/qtAgg clash) or in with jupyter as a remote server. – Lutz Lehmann Apr 09 '20 at 00:46
  • Hey, thanks for the reply! I am trying to do exactly what you explained under the question at https://stackoverflow.com/q/60925986/3088138. Still I can't get it to work and I am kind of confused. Maybe when you have the time you could head to https://stackoverflow.com/q/61110496/13024244 where I asked kind of the same question and look at my code and what mistake I am making. Or what approach I should use. – Jailbone Apr 09 '20 at 12:11