当用户单击散点图中的点时,我试图从单击中获取值。 下面显示了该图,但最后没有显示字典的值。
由于它是streamlit,所以使用bokeh==2.4.3
import streamlit as st
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource, CustomJS
# Create a Streamlit web app
st.title("Interactive Scatter Plot")
# Create some example data
data = {
"x": [1, 2, 3, 4, 5],
"y": [5, 4, 3, 2, 1],
}
# Create a Bokeh figure and add a scatter plot
p = figure(title="Click on a dot", tools="tap,reset")
source = ColumnDataSource(data=data)
scatter = p.circle("x", "y", size=20, source=source)
# Create a JavaScript callback function
callback_code = """
const selected_indices = cb_obj.indices;
if (selected_indices.length > 0) {
const selected_index = selected_indices[0];
const x_value = source.data['x'][selected_index];
const y_value = source.data['y'][selected_index];
clicked_data.x = x_value;
clicked_data.y = y_value;
}
"""
clicked_data = {"x": None, "y": None}
callback = CustomJS(
args={"source": source, "clicked_data": clicked_data}, code=callback_code
)
# Attach the JavaScript callback to the scatter plot
scatter.js_on_event("tap", callback)
# Display the Bokeh plot in Streamlit
st.bokeh_chart(p, use_container_width=True)
st.write(clicked_data)
您想要做的是从前端到后端获取一个值,为此您需要一个 webhook 或 websocket。它与 Bokeh/streamlit 无关。
如果您只需要更新 UI 中的某些组件,在 Bokeh 中创建所有组件,在回调中更改它,然后将整个 UI 发送到 Streamlit。
在下面的代码中,我根据所选点更新
x, y
-
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource, CustomJS, Div
from bokeh.layouts import Column
# Create a Streamlit web app
st.title("Interactive Scatter Plot")
# Create some example data
data = {
"x": [1, 2, 3, 4, 5],
"y": [5, 4, 3, 2, 1],
}
clicked_data = {"x": None, "y": None}
# Create a Bokeh figure and add a scatter plot
p = figure(title="Click on a dot", tools="tap,reset")
source = ColumnDataSource(data=data)
scatter = p.circle("x", "y", size=20, source=source)
div = Div(text = str(clicked_data))
c = Column(p, div)
# Create a JavaScript callback function
callback_code = """
const selected_indices = cb_obj.indices;
if (selected_indices.length > 0) {
const selected_index = selected_indices[0];
const x_value = source.data['x'][selected_index];
const y_value = source.data['y'][selected_index];
clicked_data.x = x_value;
clicked_data.y = y_value;
div.text = '{"x" : ' + x_value + ', "y" : ' + y_value +'}';
}
else{
div.text = '{"x" : ' + 'None' + ', "y" : ' + 'None' +'}';
}
div.change.emit();
"""
callback = CustomJS(
args={"source": source, "clicked_data": clicked_data, "div" : div}, code=callback_code
)
# Attach the JavaScript callback to the scatter plot
scatter.data_source.selected.js_on_change('indices', callback)
# Display the Bokeh plot in Streamlit
st.bokeh_chart(c, use_container_width=True)
我添加了一个带有 x 和 y 值的 div,并且我正在回调函数中根据我的选择更改 div 的文本。如果您想使用此选择来绘制/显示任何内容,请在散景本身中创建该 UI,并将完整的 UI(通过布局配置)传递给 Streamlit。