0

I have made a toy example of a streamlit plot that shows live data as follows

import streamlit as st
from random import random
from time import sleep

data = []

with st.empty():
    while True:
        st.line_chart(data)
        data.append(random())
        if len(data) > 30:
            data = data[-30:]
        sleep(0.1)

if st.toggle("Show message"):
    st.write("Meggase")

The problem is that, kind of obviously, this prevents the toggle from rendering. How can I draw an infinitely refreshing plot without making everything after it not render? Also, even though I was not able to replicate it here, in my real application this infinite loop makes the web page very unresponsive. This is mitigated by switching the while True with a for loop, even though it introduces a delay (you have to wait until the loop finishes to get the action done). Is there a better way to do a live plot on streamlit? Something that is executed once in the python script and keeps refreshing on the background would be ideal.

2 Answers 2

1

Turns out there is a wonderful feature called fragments that does exactly what I want :)

The correct code (with other corrections) would be

import streamlit as st
from random import random

if "data" not in st.session_state:
    st.session_state.data = []

@st.experimental_fragment(run_every=0.1)
def chart ():
    with st.container():
        global data
        st.line_chart(st.session_state.data)
        st.session_state.data.append(random())
        if len(st.session_state.data) > 30:
            st.session_state.data = st.session_state.data[-30:]

with st.empty():
    chart()

if st.toggle("Show message"):
    st.write("Meggase")
0

You can try rerun the script all the time. Like this:

import time

import streamlit as st
from random import random


if not st.session_state.get('data'):
    st.session_state['data'] = []
data = st.session_state['data']
data.append(random())
if len(data) > 30:
    data = data[-30:]
st.session_state['data'] = data
st.line_chart(data)
if st.toggle("Show message"):
    st.write("Meggase")
time.sleep(0.1)
st.rerun()

It's works,but i think there have some better way.

1
  • This kind of solutions cause very noticeable flickering for my application. Also, the elements rendered last appear very briefly on the screen.
    – Cnoob
    Commented Jul 10 at 9:33

Not the answer you're looking for? Browse other questions tagged or ask your own question.