Update figure using click event from streamlit_plotly_events package

I am trying to do a simple sequence of operations

  1. Display image
  2. Get point user clicks (using streamlit_plotly_events package)
  3. Update figure to draw a box around that point. (Later code in app will analyze the region in the box.)

What is the best way to do this with streamlit? The problem I am having is it doesn’t seem possible to update a figure, since the streamlit script is always run top to bottom.

import plotly.express as px
import plotly.graph_objects as go
from skimage import data
import streamlit as st
from streamlit_plotly_events import plotly_events

img = data.camera()

def get_figure(xy_click):
    # Figure with highlight box around xy_click
    # (returns new figure, doesn't update the original figure displayed by streamlit)
    fig = px.imshow(img, color_continuous_scale="gray", zmin=0, zmax=255)
    if xy_click is not None:
        x, y = xy_click
        block_size = 32
        fig.add_shape(
            type="rect",
            x0=x, y0=y, x1=x+block_size, y1=y+block_size,
            opacity=0.25,
            fillcolor="crimson",
        )
    return fig

fig = get_figure(None)
selected_points = plotly_events(fig)

# Goal: update original figure with click
# I can't figure out how to do this.  Current code creates a new figure
if len(selected_points) != 0:
    xy_click = (selected_points[0]["x"], selected_points[0]["y"])
    fig = get_figure(xy_click)
    st.plotly_chart(fig)

This is the current output when I click the image region right above the camera. It produces two figures, which is not desired. I want only one figure with the box drawn on it.

Hi @ngallo1

To prevent showing 2 instances of the image (original and updated version) you can use st.empty() where the updated image will replace the original image.

Consider the following example that shows this:

placeholder = st.empty()
placeholder.write("Hello")
placeholder.write("World!")

Hope this helps!

I don’t think that works with the plotly_events call

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