Black Lives Matter. Please consider donating to Black Girls Code today.

SIR model with JupyterDash

The project below presents graphs for S, I, and R in the so called SIR-model.
My final goal is to include actual corona-data from some web-site from some (preferably electable) country in order to compare the data with the model.
How can I do that?

Poul Riis
Denmark

from jupyter_plotly_dash import JupyterDash
import numpy as np
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.graph_objs as go
from scipy.integrate import odeint

Total population, Npop.

Npop = 1000

Initial number of infected and recovered individuals, I0 and R0.

I0, R0 = 1, 0

Everyone else, S0, is susceptible to infection initially.

S0 = N - I0 - R0

Contact rate, beta, and mean recovery rate, gamma, (in 1/days).

beta, gamma = 0.1, 0.1

A grid of time points (in days)

t = np.linspace(0, 160, 160)

The SIR model differential equations.

def deriv(y, t, Npop, beta, gamma):
S, I, R = y
dSdt = -beta * S * I / Npop
dIdt = beta * S * I / Npop - gamma * I
dRdt = gamma * I
return dSdt, dIdt, dRdt

Initial conditions vector

y0 = S0, I0, R0

Integrate the SIR equations over the time grid, t.

ret = odeint(deriv, y0, t, args=(Npop, beta, gamma))
S, I, R = ret.T

xp=np.linspace(0, 1,num=99,endpoint=True)
beta=0.2
gamma=0.1

app = JupyterDash(‘JupyterDashSIR’)

app.layout = html.Div([
dcc.Graph(
id=‘Sine wave’,
figure={
‘data’: [
go.Scatter(
x=t,
y=S/Npop,
text=‘Actual point’,
mode=‘lines+markers’,
opacity=0.8,
marker={
‘size’: 2,
‘line’: {‘width’: 0.5, ‘color’: ‘blue’}
}
),
go.Scatter(
x=t,
y=I/Npop,
text=‘Actual point’,
mode=‘lines+markers’,
opacity=0.8,
marker={
‘size’: 2,
‘line’: {‘width’: 0.5, ‘color’: ‘red’}
}
),
go.Scatter(
x=t,
y=R/Npop,
text=‘Actual point’,
mode=‘lines+markers’,
opacity=0.8,
marker={
‘size’: 2,
‘line’: {‘width’: 0.5, ‘color’: ‘green’}
}
)
],
‘layout’: go.Layout(
xaxis={‘type’: ‘linear’, ‘title’: ‘time (days)’},
yaxis=dict(range=[0,1.01],title=‘S/I/R’),
hovermode=‘closest’
)
}
),
html.Label(‘Beta parameter slider’),
dcc.Slider(id=‘betaslider’,min=0,max=1,value=beta,step=0.01,
marks={i/10: {‘label’: str(i/10), ‘style’: {‘color’: ‘red’}} for i in range(0, 10)}),
html.Label(‘Gamma parameter slider’),
dcc.Slider(id=‘gammaslider’,min=0,max=0.25,value=gamma,step=0.01,marks={i/100:str(i/100) for i in range(25)}),
html.Div(id=‘slider-output-container’)
])

@app.callback(
[dash.dependencies.Output(‘slider-output-container’, ‘children’),
dash.dependencies.Output(‘Sine wave’, ‘figure’)],
[dash.dependencies.Input(‘betaslider’, ‘value’),dash.dependencies.Input(‘gammaslider’, ‘value’)])

def update_output(beta,gamma):
#yp=gammanp.sin(2betanp.pixp) # calculate the new value
#yq=gammanp.cos(2betanp.pixp)
ret = odeint(deriv, y0, t, args=(Npop, beta, gamma))
S, I, R = ret.T

graph= { # update the graph content with the new value
    'data': [
    go.Scatter(
    x=t,
    y=S/Npop,
    text='Actual point',
    mode='lines+markers',
    opacity=0.8,
    marker={
    'size': 2,
    'line': {'width': 0.5, 'color': 'blue'}
    }
    ),
    go.Scatter(
    x=t,
    y=I/Npop,
    text='Actual point',
    mode='lines+markers',
    opacity=0.8,
    marker={
    'size': 2,
    'line': {'width': 0.5, 'color': 'red'}
    }
    ),
    go.Scatter(
    x=t,
    y=R/Npop,
    text='Actual point',
    mode='lines+markers',
    opacity=0.8,
    marker={
    'size': 2,
    'line': {'width': 0.5, 'color': 'green'}
    }
    )
    ],
    'layout': go.Layout(
    xaxis={'type': 'linear', 'title': 'time (days)'},
    yaxis=dict(range=[0,1.01],title='S/I/R'),
    hovermode='closest'
    )
    }
return [beta,gamma],graph # pass the two outputs in Array

app