Hi all,
I am trying to make interact two scatterplots and an histogram chart using bokeh.
I think I have to use a single ColumnDataSource
to enable interactions between my two scatter plots. Then I would have retrieved the data from the selections made through either one or the other scatter plot to feed an histogram chart using streamlit_bokeh_events
.
The ColumnDataSource contains columns x, y and yres and the expected plots are the following:
-
Scatter plot 1 : y=f(x)
-
Scatter plot 2 : yres=f(x)
-
Histogram : distribution of yres
Trying to do so I am facing problems with ColumnDataSource sharing in streamlit:
RuntimeError: Models must be owned by only a single document, Selection(id='7644', ...) is already in a doc
My sample code:
import streamlit as st
import pandas as pd
import random
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.plotting import figure
from streamlit_bokeh_events import streamlit_bokeh_events
st.set_page_config(layout="wide")
@st.cache()
def get_y(x):
return [i*i*i*(1 + random.randint(-100,100)/1000) for i in x]
x = range(1,100,1)
y = get_y(x)
yref = [i*i*i for i in x]
df = pd.DataFrame(dict(x=x, y=y))
df['yest'] = yref
df['yres'] = df['y'] - df['yest']
df.reset_index()
# create plot
cds = ColumnDataSource(df)
# define events
cds.selected.js_on_change(
"indices",
CustomJS(
args=dict(source=cds),
code="""
document.dispatchEvent(
new CustomEvent("INDEX_SELECT", {detail: {data: source.selected.indices}})
)
"""
)
)
tools = 'box_select,reset'
def xy(x,y):
xy = figure(tools=tools)
xy.circle(x=x, y=y, source=cds)
r = streamlit_bokeh_events(
bokeh_plot=xy,
events="INDEX_SELECT",
key=x+y,
refresh_on_update=True,
debounce_time=0
)
_indices = []
if r:
if r.get("INDEX_SELECT"):
_indices.extend(r.get("INDEX_SELECT")["data"])
xy('x','y')
xy('x','yres')
Any help would be appreciated.
Thanks