Streamlit (graph output without data)

Viewed 3136

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, PyCharn and Colab but here it does not work and is displayed just empty, like a white sheet.

Colab

Here's what it outputs localhost streamlit

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
2 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)

Screenshot of streamlit working.

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)
Related