Streamlit (graph output without data)
Question:
I want to implement the output of the chart using streamlit. There is a model and initial data. Previously, the chart was displayed in Speeder, PyCharm, and Colab, but here it does not work and is displayed just empty, like a white sheet.
Here’s what it outputs localhost streamlit
def SIR(y, t, N, beta, gamma):
S, I, R = y
dSdt = -beta * S * I / N
dIdt = beta * S * I / N - gamma * I
dRdt = gamma * I
return dSdt, dIdt, dRdt
N = 1000
beta = 1.0
D = 4.0
gamma = 1.0 / D
S0, I0, R0 = 999, 1, 0
t = np.linspace(0, 49, 50)
y0 = S0, I0, R0
ret = odeint(SIR, y0, t, args=(N, beta, gamma))
S, I, R = ret.T
def plotsir(t, S, I, R):
f, ax = plt.subplots(1,1,figsize=(10,4))
ax.plot(t, S, 'b', alpha=0.7, linewidth=2, label='Susceptible')
ax.plot(t, I, 'y', alpha=0.7, linewidth=2, label='Infected')
ax.plot(t, R, 'g', alpha=0.7, linewidth=2, label='Recovered')
ax.set_xlabel('Time (days)')
ax.yaxis.set_tick_params(length=0)
ax.xaxis.set_tick_params(length=0)
ax.grid(b=True, which='major', c='w', lw=2, ls='-')
legend = ax.legend()
legend.get_frame().set_alpha(0.5)
for spine in ('top', 'right', 'bottom', 'left'):
ax.spines[spine].set_visible(False)
plt.show()
st.pyplot(plt)
Making import:
import streamlit as st
from scipy.integrate import odeint
import numpy as np
import matplotlib.pyplot as plt
Answers:
So your error is that you never call plotsir(t, S, I, R). And plt.show() doesn’t work with streamlit. Use instead st.pyplot(). The working code:
import streamlit as st
from scipy.integrate import odeint
import numpy as np
import matplotlib.pyplot as plt
def SIR(y, t, N, beta, gamma):
S, I, R = y
dSdt = -beta * S * I / N
dIdt = beta * S * I / N - gamma * I
dRdt = gamma * I
return dSdt, dIdt, dRdt
N = 1000
beta = 1.0
D = 4.0
gamma = 1.0 / D
S0, I0, R0 = 999, 1, 0
t = np.linspace(0, 49, 50)
y0 = S0, I0, R0
ret = odeint(SIR, y0, t, args=(N, beta, gamma))
S, I, R = ret.T
def plotsir(t, S, I, R):
f, ax = plt.subplots(1,1,figsize=(10,4))
ax.plot(t, S, 'b', alpha=0.7, linewidth=2, label='Susceptible')
ax.plot(t, I, 'y', alpha=0.7, linewidth=2, label='Infected')
ax.plot(t, R, 'g', alpha=0.7, linewidth=2, label='Recovered')
ax.set_xlabel('Time (days)')
ax.yaxis.set_tick_params(length=0)
ax.xaxis.set_tick_params(length=0)
ax.grid(b=True, which='major', c='w', lw=2, ls='-')
legend = ax.legend()
legend.get_frame().set_alpha(0.5)
for spine in ('top', 'right', 'bottom', 'left'):
ax.spines[spine].set_visible(False)
st.pyplot()
plotsir(t, S, I, R)
After December 1st, 2020, Streamlit will remove the ability to call st.pyplot() without any arguments. It requires the use of Matplotlib’s global figure object, which is not thread-safe.
Instead st.pyplot(fig) with fig object. Example :
>>> fig, ax = plt.subplots()
>>> ax.scatter([1, 2, 3], [1, 2, 3])
>>> ... other plotting actions ...
>>> st.pyplot(fig)
That means the ‘ f ‘ variable from the solution provided…
f, ax = plt.subplots(1,1,figsize=(10,4))
…has to be passed like the argument of st.pyplot(), at the end of the function like this:
st.pyplot(f)
I want to implement the output of the chart using streamlit. There is a model and initial data. Previously, the chart was displayed in Speeder, PyCharm, and Colab, but here it does not work and is displayed just empty, like a white sheet.
Here’s what it outputs localhost streamlit
def SIR(y, t, N, beta, gamma):
S, I, R = y
dSdt = -beta * S * I / N
dIdt = beta * S * I / N - gamma * I
dRdt = gamma * I
return dSdt, dIdt, dRdt
N = 1000
beta = 1.0
D = 4.0
gamma = 1.0 / D
S0, I0, R0 = 999, 1, 0
t = np.linspace(0, 49, 50)
y0 = S0, I0, R0
ret = odeint(SIR, y0, t, args=(N, beta, gamma))
S, I, R = ret.T
def plotsir(t, S, I, R):
f, ax = plt.subplots(1,1,figsize=(10,4))
ax.plot(t, S, 'b', alpha=0.7, linewidth=2, label='Susceptible')
ax.plot(t, I, 'y', alpha=0.7, linewidth=2, label='Infected')
ax.plot(t, R, 'g', alpha=0.7, linewidth=2, label='Recovered')
ax.set_xlabel('Time (days)')
ax.yaxis.set_tick_params(length=0)
ax.xaxis.set_tick_params(length=0)
ax.grid(b=True, which='major', c='w', lw=2, ls='-')
legend = ax.legend()
legend.get_frame().set_alpha(0.5)
for spine in ('top', 'right', 'bottom', 'left'):
ax.spines[spine].set_visible(False)
plt.show()
st.pyplot(plt)
Making import:
import streamlit as st
from scipy.integrate import odeint
import numpy as np
import matplotlib.pyplot as plt
So your error is that you never call plotsir(t, S, I, R). And plt.show() doesn’t work with streamlit. Use instead st.pyplot(). The working code:
import streamlit as st
from scipy.integrate import odeint
import numpy as np
import matplotlib.pyplot as plt
def SIR(y, t, N, beta, gamma):
S, I, R = y
dSdt = -beta * S * I / N
dIdt = beta * S * I / N - gamma * I
dRdt = gamma * I
return dSdt, dIdt, dRdt
N = 1000
beta = 1.0
D = 4.0
gamma = 1.0 / D
S0, I0, R0 = 999, 1, 0
t = np.linspace(0, 49, 50)
y0 = S0, I0, R0
ret = odeint(SIR, y0, t, args=(N, beta, gamma))
S, I, R = ret.T
def plotsir(t, S, I, R):
f, ax = plt.subplots(1,1,figsize=(10,4))
ax.plot(t, S, 'b', alpha=0.7, linewidth=2, label='Susceptible')
ax.plot(t, I, 'y', alpha=0.7, linewidth=2, label='Infected')
ax.plot(t, R, 'g', alpha=0.7, linewidth=2, label='Recovered')
ax.set_xlabel('Time (days)')
ax.yaxis.set_tick_params(length=0)
ax.xaxis.set_tick_params(length=0)
ax.grid(b=True, which='major', c='w', lw=2, ls='-')
legend = ax.legend()
legend.get_frame().set_alpha(0.5)
for spine in ('top', 'right', 'bottom', 'left'):
ax.spines[spine].set_visible(False)
st.pyplot()
plotsir(t, S, I, R)
After December 1st, 2020, Streamlit will remove the ability to call st.pyplot() without any arguments. It requires the use of Matplotlib’s global figure object, which is not thread-safe.
Instead st.pyplot(fig) with fig object. Example :
>>> fig, ax = plt.subplots()
>>> ax.scatter([1, 2, 3], [1, 2, 3])
>>> ... other plotting actions ...
>>> st.pyplot(fig)
That means the ‘ f ‘ variable from the solution provided…
f, ax = plt.subplots(1,1,figsize=(10,4))
…has to be passed like the argument of st.pyplot(), at the end of the function like this:
st.pyplot(f)