Hi everyone,
I’m building a Streamlit app locally to visualize image embeddings with an interactive Plotly scatter plot. My goal is to allow users to click on a data point and see the corresponding image.
The Plotly figure (go.Figure
) displays correctly with all data points when I use st.plotly_chart(fig)
. However, as soon as I wrap the figure with plotly_events
to capture click events, the chart renders completely empty— no data but has axes .
I’ve confirmed that the data being passed to create the figure (numpy arrays for x, y coordinates, labels, etc.) is valid and has the correct shape.and it works perfectly fine with plotly .chart The issue seems to be specifically with the streamlit-plotly-events
component.
Here is the relevant code snippet from my app:
import streamlit as st
import numpy as np
import plotly.graph_objects as go
from streamlit_plotly_events import plotly_events
def create_interactive_plot(baseline_2d, new_2d, new_labels, new_urls):
"""Creates the Plotly figure."""
fig = go.Figure()
# Add baseline data (displays correctly)
fig.add_trace(go.Scatter(
x=baseline_2d[:, 0], y=baseline_2d[:, 1], mode='markers',
marker=dict(color='lightgray', size=7), name='Baseline', hoverinfo='none'
))
# Add new data with customdata for the click event (displays correctly)
custom_data = np.stack((new_urls, new_labels.astype(str)), axis=-1)
fig.add_trace(go.Scatter(
x=new_2d[:, 0], y=new_2d[:, 1], mode='markers',
marker=dict(color=new_labels, colorscale='Viridis', size=10),
name='Current', customdata=custom_data,
hovertemplate='<b>Cluster ID</b>: %{customdata[1]}<extra></extra>'
))
fig.update_layout(title="Embedding Visualization", height=600, clickmode='event+select')
return fig
# --- In the main Streamlit UI section ---
# Dummy data for reproducibility
baseline_2d = np.random.rand(100, 2)
new_2d = np.random.rand(100, 2)
new_labels = np.random.randint(0, 5, 100)
new_urls = [f"http://example.com/img_{i}.png" for i in range(100)]
# Create the figure
plot_fig = create_interactive_plot(baseline_2d, new_2d, new_labels, new_urls)
# This works fine and shows the plot:
# st.plotly_chart(plot_fig)
# This shows a blank area where the plot should be:
plot_col, preview_col = st.columns([3, 1])
with plot_col:
selected_points = plotly_events(plot_fig, click_event=True, key="plot_click")
with preview_col:
if selected_points:
st.write("Point selected!")
else:
st.write("Click a point.")
Environment:
streamlit==1.46.0
streamlit-plotly-events==0.0.6
Python 3.10.13