Plotly_event re-renders the plot after selecting datapoints

I can select datapoints in my plot, get theire indexes, and filter a dataframe based on those indexes. So far so good.
While i select datapoints, they show as highlighted. As soon as i select them, the plot is rerenderd loosing the selected items. So after selection i have the info i selected in the dataframe below, but i am not seeing my selection anymore.
This is my crrent code:

with st.expander("TSNE  Parameter", expanded=False):

        #copydf is a dataframe
        copydf = st.session_state.dataUpdated.copy()
        data2D = tsne(copydf, perplexity, learning_rate)

        st.session_state.plot = renderplot(data2D)
        fig = st.session_state.plot

        selected_data = plotly_events(fig, click_event=True, select_event=True, key="pe_selected")

        # show selected data in widget
        if selected_data is not None:
            # extrahiere die x- und y-Werte für die ausgewählten Punkte
            x_selected = [i['x'] for i in selected_data]
            y_selected = [i['y'] for i in selected_data]

            # find index of selected datapoints
            idx_selected = []
            for x, y in zip(x_selected, y_selected):
                selectedRows = data2D[(data2D['tsne-2d-one'] == x) & (data2D['tsne-2d-two'] == y)]
                idx =selectedRows.index.astype(int)[0]
                idx_selected.append(idx)

            #Extract columns for new dataframe
            df_selected = copydf.loc[idx_selected, ['SAG-Nummer', 'TicketID', 'Text', 'Tokens','Gelöst']]
            if not df_selected.empty:
                st.dataframe(df_selected)

What i want is to keep the selected datapoints in the plot. I gues i need to prevent streamlit rendering the component again.


the screenshot shows my app after i selected those 2 datapoints. As you can see they are not selected in the plot but “extracted” into the dataframe

I think it might be my session state objects.

if st.form_submit_button("Los"):
            st.cache_data.clear()
            st.session_state.firstRun = False
            st.session_state.dataSubmitted = fetchData(st.session_state.nlp)
            st.session_state.dataUpdated = st.session_state.dataSubmitted

Streamlit starts and some session states are initialized. I can select some params in a form and run a sql query when the submit button is pressed. fetchData returns a dataframe, which is then copied to the session state dataUpdated.

in a second form i can further alter the data and update the session_state.dataUpdated.

        data2D = tsne(st.session_state.dataUpdated, perplexity, learning_rate)
        fig = renderplot(data2D)
        selected_data = plotly_events(fig, click_event=True, select_event=True)

any idea how cleanup the session state chaos? Or is that the correct way?

Edit: I have rebuild the app to use no more session states and its the same result. So it mus be something with the caching. On the first run it renders the plot, but my selection doesnt show in the dataframe below, instead it seams to rerun and rerender the plot after the first selection. On my second selection it shows the dataframe and selected points below the plot and rerenders again.

Found the solution!
When creating the figure i needed to add this plotly layout parameter:

fig['layout']['uirevision'] = True

Now the plotly_event keeps the zoom-level and selection

3 Likes

Hi @Eric ,
where did you add that layout parameter?
Before calling plotly_events() ?

Sorry for the late reply. Yes, the parameter is set before calling plotly_events. in my example its set in the renderplot-function which returns the fig:

 if st.session_state.data_umap is not None:
                    fig = renderplot(st.session_state.data_umap, hovermode, withUmap=True, dimension=n_components, color=selected_color)

                selected_data = plotly_events(fig, click_event=False, select_event=True, key="event1")