Experimental Fragment Flickering Streamlit Chart Elements

  1. Are you running your app locally or is it deployed?
    I am running the app locally on 1.36.0

When refreshing data inside an experiement_fragment with run_every parameter set, the visualisation will flicker (fade out / in) in line with the amount of time it takes to refresh/update the data.

In the example below you can simulate/adapt this behaviour by updating this section of code.

        # comment this line in/out to simulate expected/flickering behaviour
        import time
        time.sleep(3)

Is there anyway to avoid this flickering? In my real example, my update_data function takes about 1-2 second to check if new data exists/pull the data. In turn this means the plot fades in out (for a period of 1-2 seconds) every time the fragment re-runs (every 1 second.) This creates flicker, even though the data is not updating.

The flickering is independent on whether or not st.line_chart(data) is actually called. e.g. if you have some logic which says only call st.line_chart(data) if the data updates, the flickering still occurs.

The problem is not line_chart specific, I’ve tried with a few visual elements and I have the same problem.

import streamlit as st


from pages.example_components.datasets.example_data import ExampleData

import numpy as np
class ExampleData():
    def __init__(self):
        self.max_points = 50
        self.amplitude = 1
        self.frequency = 1
        self.phase_increment = 0.1
        self.x_values = np.linspace(0, 10, self.max_points)
        self.y_values = self.amplitude * np.sin(self.frequency * self.x_values)
        self.current_phase = 0

    def init_dataset(self):
        if self.name not in st.session_state:
            data = np.ones(30)
            st.session_state[self.name] = data
            return data
        else:
            data = st.session_state[self.name]
            return data

    def update_dataset(self):
        self.current_phase += self.phase_increment
        self.y_values = self.amplitude * np.sin(self.frequency * self.x_values + self.current_phase)
        return self.y_values


class ExamplePageRunner():
    def __init__(self):
        """Initialise all streamlit components and datasets components required to run page."""
        #  Set Page Config
        st.set_page_config(
            layout="wide",
            initial_sidebar_state="expanded",
        )
        # Init Components and Data
        self.extractor = ExampleData()
        self.line_chart_container = st.empty()

    def run(self):
        # Run Fragment to Refresh Data and Visualizations
        self.live_refresh()

    @st.experimental_fragment(run_every=1.0)
    def live_refresh(self):
        # Start Looping To Refresh Data and Visualizations
        data = self.extractor.update_dataset()  # Update Data

        # comment this line in/out to simulate expected/flickering behaviour
        import time
        time.sleep(3)

        # Render Line Chart in Container
        with self.line_chart_container:
            st.line_chart(data)


ExamplePageRunner().run()

This GIF shows the behaviour I’m describing - although the timing doesn’t quite align the the screen recording I took (3 seconds data update time.)
Screen Recording 2024-07-08 at 12.10.37

Is there a workaround for this? Or another way to structure the code to prevent this from happening?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.