Best practice for real-time app

Hi everyone,

My idea is to develop an app that takes data from mongoDB database. It will pull out from the MongoDB data at every fixed time-step (so far I have fixed every 5 min). Then, I will turn into dataframes, perform some calculations and plot some results. The idea is to present both accomolative results and results related to the real-time data. I would to know if anyone has an example code (with similar characteristics), or recommend best packages to execute that - packages like to plot real-time data.

The ‘Plotting’ demo from streamlit hello does something similar to what you are describing:

import time
import numpy as np

progress_bar = st.sidebar.progress(0)
status_text = st.sidebar.empty()
last_rows = np.random.randn(1, 1)
chart = st.line_chart(last_rows)

for i in range(1, 101):
    new_rows = last_rows[-1, :] + np.random.randn(5, 1).cumsum(axis=0)
    status_text.text("%i%% Complete" % i)
    last_rows = new_rows


# Streamlit widgets automatically run the script from top to bottom. Since
# this button is not connected to any other logic, it just causes a plain
# rerun.

The key line is chart.add_rows(new_rows), which appends data frame rows to a chart object. When you do this, the app knows that an input has changed and re-renders the graph appropriately.



1 Like

Using this method, the rest of the code won’t get executed until the end of the for loop.
Is there a way to run the loop in the “background” while letting the rest of the code run? Is there where the “async” technique comes into handle?

This eventually runs for a certain durations and halts.
It can also be achieved with a similar condition for the seamless running of the chart.
is there a way to control the data rows(last_rows) inside the chart?
If I want to restrict the data points inside the chart( to show only last 10 points).

    import time
    import numpy as np
    last_rows = np.random.randn(1, 1)
    chart = st.line_chart(last_rows)
    i = 0
    while True:
        i += 1
        new_rows = last_rows[-1, :] + np.random.randn(5, 1).cumsum(axis=0)
        last_rows = new_rows

The above solution doesn’t work for live data. In order to make the the live charts. for live time series data.

from bokeh.models import AjaxDataSource, CustomJS

adapter = CustomJS(code= “”"
const result = {x: , y: }
const x= cb_data.response.x
const y= cb_data.response.x
for (let i=0; i<x.length; i++) {
return result

    source = AjaxDataSource(data_url='http://localhost:5050/api/data',
                    polling_interval=1000, adapter=adapter, 

Sample:- Ajax API Response in json format

       {"x":[1,3,3,4], 'y':[1,5,6,7]}


I was able to create a dynamic radar chart that continuously updates with a stream of data using a ‘st.empty()’ placeholder to write my chart to and a while loop to continuously re-run the chart.

You can see a demo app and my source code here:


Oh that is very nice. I have an application for it…

Great demonstration @mkhorasani! Do you have a Streamlit sharing invite? If so, it’d be a great example for the community to see live…if not, send me a direct message and we’ll get you set up :100:


Hey @randyzwitch, I just deployed this app on Streamlit sharing as per your recommendation! Please find it here.

1 Like

Hi Randy,

is it possible to use the add_row function also with Plotly?
I didnt archive it. I tried to create a like that: chart = st.plotly_chart(“data”) and then chart.add_rows(new_rows). It didnt worked.

I don’t believe add_rows works with Plotly, but I think Plotly itself has its own version of appending data into a chart dynamically.