Component for bi-directional communication with bokeh

Hey @blob123,

I whipped up something based on my previous answer.
Got it working working with some bokeh magic. Is it what you’re looking for ?

from streamlit_bokeh_events import streamlit_bokeh_events
from bokeh.plotting import figure
from bokeh.models import PointDrawTool, ColumnDataSource, CustomJS
import pandas as pd
import streamlit as st


def plot_and_move(df):
    p = figure(x_range=(0, 10), y_range=(0, 10), tools=[],
            title='Point Draw Tool')

    source = ColumnDataSource(df)

    renderer = p.scatter(x='x', y='y', source=source, size=10)

    draw_tool = PointDrawTool(renderers=[renderer])
    p.add_tools(draw_tool)
    p.toolbar.active_tap = draw_tool

    source.js_on_change("data", CustomJS(
        code="""
            document.dispatchEvent(
                new CustomEvent("DATA_CHANGED", {detail: cb_obj.data})
            )
        """
    ))

    event_result = streamlit_bokeh_events(p, key="foo", events="DATA_CHANGED", refresh_on_update=False, debounce_time=0)

    if event_result:
        df_values = event_result.get("DATA_CHANGED")
        return pd.DataFrame(df_values, index=df_values.pop("index"))
    else:
        return df


df = pd.DataFrame({
        'x': [1, 5, 9], 'y': [1, 5, 9]
})

st.write(plot_and_move(df))

Hope it helps !

2 Likes