Hi, I am new to Streamlit, and I am trying to make an interactive scatter plot where you can click to select a datapoint from a plot, and then click again to de-select it. And I want this to happen without re-drawing the whole plot (without flickering on the screen).
Problem is that whenever I move the mouse, the plot loses its clickability.
- You can see that on the first click, It re-draws the whole thing, and screen flickers, which is not intended, but ok.
- For the next 4 clicks, it works normally. Every time I click, it selects it and changes color without re-drawing the whole thing.
- But after I move the mouse, I try clicking, and it wouldn’t change color.
I have attached my code below.
I was wondering if anybody can help me fix the issue where it loses its clickability after mouse movement, and if there is a better way to make a interactive and clickable scatterplot other then plotly. Thank you.
Note: There is only one data point for now, for debugging purpose. It should work for multiple points
import streamlit as st
import plotly.graph_objects as go
from streamlit_plotly_events import plotly_events
import streamlit.components.v1 as components
# Initialize session state
if 'selected' not in st.session_state:
st.session_state.selected = False
# Create the plot
def create_plot():
fig = go.Figure()
# Add the single datapoint
fig.add_trace(go.Scatter(
x=[1],
y=[1],
mode='markers',
marker=dict(
size=20,
color='blue' if st.session_state.selected else 'lightblue',
),
name='Datapoint'
))
# Set layout
fig.update_layout(
title='Interactive Plot',
xaxis_title='X Axis',
yaxis_title='Y Axis',
uirevision='constant'
)
fig['layout']['uirevision'] = True
return fig
# Initialize plot
if 'fig' not in st.session_state:
st.session_state.fig = create_plot()
# Create a placeholder for the plot
plot_placeholder = st.empty()
with plot_placeholder.container():
selected_points = plotly_events(
st.session_state.fig,
click_event=True,
override_height="400px",
key='interactive_plot'
)
# Handle selection
if selected_points:
st.session_state.selected = not st.session_state.selected
st.session_state.fig.data[0].marker.color = 'blue' if st.session_state.selected else 'lightblue'
with plot_placeholder.container():
plotly_events(
st.session_state.fig,
click_event=True,
override_height="400px",
key='interactive_plots'
)
# Display selection state
st.write(f"Point selected: {st.session_state.selected}")