Continuously updating dashboard

Love using this project so far!

Our key application of this tool would be a live dashboard reading data from sensors and continuously updating their state and history. In order to do that I want the page to automatically update every second or so.

I can get this to work by abusing a while loop like this:

state = run(read_plc())
json_view = st.json(state)
line_chart = st.line_chart([{key: val for key, val in state.items()}])
while True:
    time.sleep(1)
    state = run(read_plc())
    json_view.json(state)
    line_chart.add_rows([{key: val for key, val in state.items()}])

But that feels like it’s abusing the abstraction a bit. Is there a better way to achieve this behavior? I’d love a method to specify an update frequency.

1 Like

Actually. To me thats the beauty of streamlit that you can do it like that.

Hi @JamesJeffryes, this is a very interesting use-case. The code you are suggesting will work, but we are working at providing first-class support for dashboards. To give you some context, by wrapping your logic inside the while True loop, Streamlit will not release resources (thread and connection) while a user is connected. Streamlit will release resources once the user disconnects. Depending on your specifics this may or may not be acceptable. In general, we think that the code of a Streamlit App should run to completion and re-runs should be used on changes.

Unfortunately, it is not possible at the moment to programmatically trigger re-runs, but we are investigating whether it makes sense to implement a mechanism to allow that. By programmatically triggering a re-run, you would be able to control when re-executing and pulling new data. If you are interested, I can provide a gist on top of Streamlit to try that out and definitely I will keep you posted on the progress of this feature.

Matteo

2 Likes

I’d definitely be interested in programmatic triggers for re-runs. Streamlet seems to abstract away web concepts better than any other python library I’ve played with so I think there could be real interest in using it to make simple interfaces for IoT devices. Not releasing resources while the user is connected would likely be fine for our use cases, especially if the websocket is reconnecting.

1 Like

Thanks @JamesJeffryes. I opened a feature request for reruns: https://github.com/streamlit/streamlit/issues/514

I do think another piece of the problem is how to keep some state between re-runs. We are looking at solutions for this as well.

Matteo

1 Like

This is a small gist that implements a sliding-window dashboard-style plot that periodically pulls from a random generator: https://gist.github.com/monchier/4ba216cc9168a7d2bea7f3f31a1c4491

It uses two other gists that we are considering merging into Streamlit, but you should be able to use them right now. One gist implements reruns, the other one implements SessionState. The gist above has the links to the other two.

Best,
Matteo

Hello,
I am trying to develop a dashboard too. However, I would like to keep the sensor data collection isolated from the dashboard. So I spawn them within two different processes. The code runs without errors but does not output anything? How to use streamlit within a subprocess? Or what is the best way to isolate these two parts. Code snippet:

def collect_data():
    while True:
        s = read_sensor_data()
        send_data_to_db()

def dashboard():
    while True:
        df = pd.read_sql(...)
        st.dataframe(df)

p1 = mp.Process(collect_data())
p2 = mp.Process(dashboard())

p1.start()
p2.start()

p1.join()
p2.join()

Result: An the default webpage spawned by streamlit.

Hello Matteo,

I have the same question, I don’t know that you solved your problem and maybe help me because I’m new in streamlit and tried to implement a solutions that found in web but I can’t solve the application.

In my aplication I designed a detector based on FPGA that send the monitoring of a sensors through serial port and is proccessing and storage with a script in python. This script create a csv file that is updated each time that the FPGA send a monitoring frame.

I wrote a other script to use streamlit to show the data of the monitoring and I push the option to load a old file or detect a new file(this files is the csv thats created in real time when my system is on operation and its updated each 2-3 seconds) .

I share the code that use for the select the source and load the data:

st.sidebar.title(“Settings”)

if not st.sidebar.checkbox(“Live Data”, True):
st.sidebar.markdown(“Choose the data file csv”)
folder_path = path_script = os.path.abspath(os.getcwd())
filenames = os.listdir(folder_path )
selected_filename = st.selectbox(‘Select a file’, filenames)
DATA_URL=os.path.join(folder_path + ‘\’ + selected_filename)


st.write('You selected `%s`' % DATA_URL)


else:
list_of_files = glob.glob(’*.csv’)
#print(list_of_files)
LASTEST_FILE = max(list_of_files, key=os.path.getctime)
#print(latest_file)
path_script = os.path.abspath(os.getcwd())
DATA_URL = path_script + ‘\’+ LASTEST_FILE

def load_data():
update_timestamp = time.ctime(os.path.getmtime(DATA_URL))
st.write(update_timestamp)
return cached_data_load(update_timestamp)

@st.cache(ttl=60)
def cached_data_load(timestamp):
data = pd.read_csv(DATA_URL)
return data

data = load_data()

#%%
st.markdown("### Rate vs Time")

f1 = alt.Chart(data).mark_circle().encode(
x=alt.X(‘Time’, axis=alt.Axis(title=“Time”)),
y=alt.Y(‘Rate’, axis=alt.Axis(title=“Rate [s^-1]”)),
color=‘Rate’
)
st.altair_chart(f1, use_container_width=True)

The dataframe is update only when I pushed a checkbox implemented on script

Could you help me please to understand why the app.py don’t update the dataframe and graph please?

Regards
Juan Carlos