import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
import pandas as pd
# Total population, N.
N = 100000
# Initial number of infected and recovered individuals, I0 and R0.
I0, R0 = 10, 0
# Everyone else, S0, is susceptible to infection initially.
S0 = N - I0 - R0
J0 = I0
# Contact rate, beta, and mean recovery rate, gamma, (in 1/days).
#reproductive no. R zero is beta/gamma
beta, gamma = 1.47617188, 1/7
# A grid of time points (in days)
t = np.linspace(0, 77, 77 1)
t1 = [1,2,3,4,5,6,7,8,9,10,11]
# The SIR model differential equations.
def deriv(y, t, N, beta, gamma):
S, I, R, J = y
dS = ((-beta * S * I) / N)
dI = ((beta * S * I) / N) - (gamma * I)
dR = (gamma * I)
dJ = ((beta * S * I) / N)
return dS, dI, dR, dJ
# Initial conditions are S0, I0, R0
# Integrate the SIR equations over the time grid, t.
solve = odeint(deriv, (S0, I0, R0, J0), t, args=(N, beta, gamma))
S, I, R, J = solve.T
d = {'Week': [1, 2,3,4,5,6,7,8,9,10,11], 'incidence': [206.1705794,2813.420201,11827.9453,30497.58655,10757.66954,7071.878779,3046.752723,1314.222882,765.9763902,201.3800578,109.8982006]}
df = pd.DataFrame(data=d)
J_diff = J[1:] - J[:-1]
J_diff = np.diff(J)
fig = plt.figure(facecolor='w')
ax = fig.add_subplot(111, facecolor='#dddddd', axisbelow=True)
ax.plot(t1, df, 'blue', alpha=1, lw=2, label='Daily incidence')
ax.set_xlabel('Time in days')
ax.set_ylabel('Number')
ax.grid(b=True, which='major', c='w', lw=2, ls='-')
legend = ax.legend()
legend.get_frame().set_alpha(0.5)
plt.show()
The code above produces the output to an ODE system, and then i create a data frame of some values that I hoped to plot along with the ODE output. I understand the time points are different, the ODE system uses days, up until 77 days. The data frame is in weeks, up until 11 weeks so still 77 days. Which is why I made the list t1 to plot the dataaframe df with. However, my code above outputs a plot with a third line, a horizontal line along the bottom of the x axis. What am I getting wrong in my code? What do I need to do to the time points to keep both outputs on my axis, the ODE output J, and df? And if I wanted to cut the axis off at day 20?
CodePudding user response:
I think you don't need to use pandas for this particular case. If you want to plot the data contained in the dictionary, you could simply do:
import numpy as np
import matplotlib.pyplot as plt
d = {'Week': np.arange(1, 12) * 7,
'incidence': [206.1705794, 2813.420201, 11827.9453, 30497.58655, 10757.66954, 7071.878779, 3046.752723, 1314.222882, 765.9763902, 201.3800578, 109.8982006]}
plt.plot(d['Week'], d['incidence'])
The reason you are getting that horizontal line is because the dataframe df you generated from d has two columns, and when you plot it, it creates two series, one for each column. Here you can see it by using the dataframe plot method directly:
df = pd.DataFrame(d)
df.plot()
which is not what you want. Additionally, note that the horizontal axis is automatically set to a counter number, i.e. your x-axis values are not the 'Week' values you have in your dictionary but rather an automatic counter (from zero to 11) set by pandas/matplotlib. If you still want to plot using pandas, you could do df.plot(x='Week', y='incidence')



