Mathematics of Epidemics on Networks by Kiss, Miller, and Simon (Springer, 2017).
Github: https://github.com/springer-math/Mathematics-of-Epidemics-on-Networks
Documentation: https://epidemicsonnetworks.readthedocs.io/en/latest/GettingStarted.html#quickstart-guide
import networkx as nx
import matplotlib.pyplot as plt
import EoN
!pip install EoN
Collecting EoN
Downloading https://files.pythonhosted.org/packages/81/4a/765f1cfa8d3a59fa14c772b4577ab70804ddc13c7521fbad00fc35b21795/EoN-1.0.3.tar.gz (65kB)
100% |████████████████████████████████| 71kB 12kB/s ta 0:00:0121
Requirement already satisfied: networkx in /Users/datalab/Applications/anaconda/lib/python3.5/site-packages (from EoN) (2.1)
Requirement already satisfied: scipy in /Users/datalab/Applications/anaconda/lib/python3.5/site-packages (from EoN) (1.1.0)
Requirement already satisfied: matplotlib in /Users/datalab/Applications/anaconda/lib/python3.5/site-packages (from EoN) (3.0.1)
Requirement already satisfied: decorator>=4.1.0 in /Users/datalab/Applications/anaconda/lib/python3.5/site-packages (from networkx->EoN) (4.2.1)
Requirement already satisfied: python-dateutil>=2.1 in /Users/datalab/Applications/anaconda/lib/python3.5/site-packages (from matplotlib->EoN) (2.6.1)
Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /Users/datalab/Applications/anaconda/lib/python3.5/site-packages (from matplotlib->EoN) (2.1.4)
Requirement already satisfied: cycler>=0.10 in /Users/datalab/Applications/anaconda/lib/python3.5/site-packages (from matplotlib->EoN) (0.10.0)
Requirement already satisfied: numpy>=1.10.0 in /Users/datalab/Applications/anaconda/lib/python3.5/site-packages (from matplotlib->EoN) (1.14.3)
Requirement already satisfied: kiwisolver>=1.0.1 in /Users/datalab/Applications/anaconda/lib/python3.5/site-packages (from matplotlib->EoN) (1.0.1)
Requirement already satisfied: six>=1.5 in /Users/datalab/Applications/anaconda/lib/python3.5/site-packages (from python-dateutil>=2.1->matplotlib->EoN) (1.11.0)
Requirement already satisfied: setuptools in /Users/datalab/Applications/anaconda/lib/python3.5/site-packages (from kiwisolver>=1.0.1->matplotlib->EoN) (39.1.0)
Building wheels for collected packages: EoN
Building wheel for EoN (setup.py) ... done
Stored in directory: /Users/datalab/Library/Caches/pip/wheels/23/9c/10/a6c8cb69ac884c10f1074deb30d3eddc137a2fd659c8becc11
Successfully built EoN
Installing collected packages: EoN
Successfully installed EoN-1.0.3
You are using pip version 19.0.2, however version 19.0.3 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
N=10**5
G=nx.barabasi_albert_graph(N, 5) #create a barabasi-albert graph
tmax = 20
iterations = 5 #run 5 simulations
tau = 0.1 #transmission rate
gamma = 1.0 #recovery rate
rho = 0.005 #random fraction initially infected
# Simulations and Models
for counter in range(iterations): #run simulations
t, S, I, R = EoN.fast_SIR(G, tau, gamma, rho=rho, tmax = tmax)
if counter == 0:
plt.plot(t, I, color = 'k', alpha=0.3, label='Simulation')
plt.plot(t, I, color = 'k', alpha=0.3)
# plot the Pref mix EBCM
t, S, I, R = EoN.EBCM_pref_mix_from_graph(G, tau, gamma, rho=rho, tmax=tmax)
plt.plot(t, I, label = 'Pref mix EBCM', linewidth=5, dashes=[4, 2, 1, 2, 1, 2])
plt.xlabel('$t$')
plt.ylabel('Number infected')
plt.legend();
Now compare with ODE predictions.
#we expect a homogeneous model to perform poorly because the degree
#distribution is very heterogeneous
t, S, I, R = EoN.SIR_homogeneous_pairwise_from_graph(G, tau, gamma, rho=rho, tmax = tmax)
plt.plot(t, I, '-.', label = 'Homogeneous pairwise', linewidth = 5)
#meanfield models will generally overestimate SIR growth because they
#treat partnerships as constantly changing.
t, S, I, R = EoN.SIR_heterogeneous_meanfield_from_graph(G, tau, gamma, rho=rho, tmax=tmax)
plt.plot(t, I, ':', label = 'Heterogeneous meanfield', linewidth = 5)
#The EBCM model does not account for degree correlations or clustering
t, S, I, R = EoN.EBCM_from_graph(G, tau, gamma, rho=rho, tmax = tmax)
plt.plot(t, I, '--', label = 'EBCM approximation', linewidth = 5)
#the preferential mixing model captures degree correlations.
t, S, I, R = EoN.EBCM_pref_mix_from_graph(G, tau, gamma, rho=rho, tmax=tmax)
plt.plot(t, I, label = 'Pref mix EBCM', linewidth=5, dashes=[4, 2, 1, 2, 1, 2])
plt.xlabel('$t$')
plt.ylabel('Number infected')
plt.legend();
# plt.savefig('SIR_BA_model_vs_sim.png')
The preferential mixing version of the EBCM approach provides the best approximation to the (gray) simulated epidemics.
We now move on to SIS epidemics:
#Now run for SIS.
# Simulation is much slower so need smaller network
N=10**4
G=nx.barabasi_albert_graph(N, 5) #create a barabasi-albert graph
# simulations
for counter in range(iterations):
t, S, I = EoN.fast_SIS(G, tau, gamma, rho=rho, tmax = tmax)
if counter == 0:
plt.plot(t, I, color = 'k', alpha=0.3, label='Simulation')
plt.plot(t, I, color = 'r', alpha=0.3)
Now compare with ODE predictions.
#we expect a homogeneous model to perform poorly because the degree
#distribution is very heterogeneous
t, S, I = EoN.SIS_homogeneous_pairwise_from_graph(G, tau, gamma, rho=rho, tmax = tmax)
plt.plot(t, I, '-.', label = 'Homogeneous pairwise', linewidth = 5)
t, S, I = EoN.SIS_heterogeneous_meanfield_from_graph(G, tau, gamma, rho=rho, tmax=tmax)
plt.plot(t, I, ':', label = 'Heterogeneous meanfield', linewidth = 5)
t, S, I = EoN.SIS_compact_pairwise_from_graph(G, tau, gamma, rho=rho, tmax=tmax)
plt.plot(t, I, '--', label = 'Compact pairwise', linewidth = 5)
plt.xlabel('$t$')
plt.ylabel('Number infected')
plt.legend();
#plt.savefig('SIS_BA_model_vs_sim.png')
# Which model is better?
for counter in range(iterations):
t, S, I = EoN.fast_SIS(G, tau, gamma, rho=rho, tmax = tmax)
if counter == 0:
plt.plot(t, I, color = 'k', alpha=0.3, label='Simulation')
plt.plot(t, I, color = 'k', alpha=0.3)
t, S, I = EoN.SIS_heterogeneous_meanfield_from_graph(G, tau, gamma, rho=rho, tmax=tmax)
plt.plot(t, I, ':', label = 'Heterogeneous meanfield', linewidth = 5)
t, S, I = EoN.SIS_compact_pairwise_from_graph(G, tau, gamma, rho=rho, tmax=tmax)
plt.plot(t, I, '--', label = 'Compact pairwise', linewidth = 5)
plt.xlabel('$t$')
plt.ylabel('Number infected')
plt.legend();
#each node is (u,v) where 0<=u,v<=99
G = nx.grid_2d_graph(100,100)
#we'll initially infect those near the middle
initial_infections = [(u,v) for (u,v) in G if 45<u<55 and 45<v<55]
sim = EoN.fast_SIS(G, 1.0, 1.0, initial_infecteds = initial_infections,
return_full_data=True, tmax = 10)
pos = {node:node for node in G}
sim.set_pos(pos)
sim.display(0, node_size = 4); #display time 6
#plt.savefig('SIS_2dgrid.png')
sim.display(1, node_size = 4); #display time 6
#plt.savefig('SIS_2dgrid.png')
sim.display(2, node_size = 4);
sim.display(3, node_size = 4);
sim.display(10, node_size = 4);
ani_sis=sim.animate(ts_plots=['S', 'I'], node_size = 4)
# brew intall ffmpeg
from IPython.display import display, HTML
display(HTML(ani_sis.to_html5_video()))
import networkx as nx
import EoN
import matplotlib.pyplot as plt
G = nx.grid_2d_graph(100,100) #each node is (u,v) where 0<=u,v<=99
#we'll initially infect those near the middle
initial_infections = [(u,v) for (u,v) in G if 45<u<55 and 45<v<55]
sim = EoN.fast_SIR(G, 2.0, 1.0, initial_infecteds = initial_infections,
return_full_data=True, tmax = 10)
pos = {node:node for node in G}
sim.set_pos(pos)
ani=sim.animate(ts_plots=['I', 'SIR'], node_size = 4)
ani.save('../vis/SIR_2dgrid.mp4', fps=5, extra_args=['-vcodec', 'libx264'])
%%HTML
<div align="middle">
<video width="80%" controls>
<source src="../vis/SIR_2dgrid.mp4" type="video/mp4">
</video></div>
from IPython.display import display, HTML
display(HTML(ani.to_html5_video()))
# from ipywidgets import interact, fixed
# interact(sim.display, time=[0, 10], node_size = 4);
https://epidemicsonnetworks.readthedocs.io/en/latest/Examples.html