Visualizing the Lotka-Volterra Model
Visualizing the Lotka-Volterra Model#
They have 4 parameters that can each be tuned individually which will affect how the flucuations in population behave. In order to explore this 4D parameter space we can use
plot function to plot the results of the integrated ODE and have the plot update automatically as we update the parameters.
Define the function#
%matplotlib ipympl import matplotlib.pyplot as plt import numpy as np from mpl_interactions import ipyplot as iplt
# this cell is based on https://scipy-cookbook.readthedocs.io/items/LoktaVolterraTutorial.html from scipy import integrate t = np.linspace(0, 15, 1000) # time X0 = np.array([10, 5]) # initials conditions: 10 rabbits and 5 foxes # use `c_` instead of `c` because `c` is an argument to plt.scatter def f(a, b, c_, d): def dX_dt(X, t=0): """Return the growth rate of fox and rabbit populations.""" rabbits, foxes = X dRabbit_dt = a * rabbits - b * foxes * rabbits dFox_dt = -c_ * foxes + d * b * rabbits * foxes return [dRabbit_dt, dFox_dt] X, _ = integrate.odeint(dX_dt, X0, t, full_output=True) return X # expects shape (N, 2)
Make the plots#
Here we make two plots. On the left is a parametric plot that shows all the possible combinations of rabbits and foxes that we can have. The plot on the right has time on the X axis and shows how the fox and rabbit populations evolve in time.
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(10, 4.8)) controls = iplt.plot(f, ax=ax1, a=(0.5, 2), b=(0.1, 3), c_=(1, 3), d=(0.1, 2), parametric=True) ax1.set_xlabel("rabbits") ax1.set_ylabel("foxes") iplt.plot(f, ax=ax2, controls=controls, label=["rabbits", "foxes"]) ax2.set_xlabel("time") ax2.set_ylabel("population") _ = ax2.legend()
You may have noticed that it looks as though we will end up calling our function
f twice every time we update the parameters. This would be a bummer because then our computer would be doing twice as much work as it needs to. Fortunately the
control object implements a cache and will avoid call a function more than necessary when we move the sliders.
If for some reason you want to disable this you can disable it by setting the
use_cache attribute to
controls.use_cache = False