我修改了this example。我最终想要的是一种在图形中选择数据点并在python代码中修改它们的方法。因此我在这里添加了一个函数,它应该从第二个图形中返回值(这就是按钮的用途)。但是,如果我选择了这些点,它们会被正确绘制,但数据源不会更改(按钮单击提供{'X':[],'Y':[]}。如何从JS写回到python散景数据源?是不是s2.change.emit()或s2.trigger('change')应该这样做?我也尝试了后者但它不起作用。
from random import random
from bokeh.layouts import row
from bokeh.models import CustomJS, ColumnDataSource
from bokeh.plotting import figure
from bokeh.models.widgets import Button
from bokeh.io import curdoc
x = [random() for x in range(500)]
y = [random() for y in range(500)]
s1 = ColumnDataSource(data=dict(x=x, y=y))
p1 = figure(plot_width=400, plot_height=400, tools="lasso_select", title="Select Here")
p1.circle('x', 'y', source=s1, alpha=0.6)
s2 = ColumnDataSource(data=dict(x=[], y=[]))
p2 = figure(plot_width=400, plot_height=400, x_range=(0, 1), y_range=(0, 1),
tools="", title="Watch Here")
p2.circle('x', 'y', source=s2, alpha=0.6)
s1.selected.js_on_change('indices', CustomJS(args=dict(s1=s1, s2=s2), code="""
var inds = cb_obj.indices;
var d1 = s1.data;
var d2 = s2.data;
d2['x'] = []
d2['y'] = []
for (var i = 0; i < inds.length; i++) {
d2['x'].push(d1['x'][inds[i]])
d2['y'].push(d1['y'][inds[i]])
}
s2.change.emit();
""")
)
def get_values():
global s2
print(s2.data)
button = Button(label="Get selected set")
button.on_click(get_values)
layout = row(p1, p2,button)
curdoc().add_root(layout)
curdoc().title = "my dashboard"
单击按钮时,此代码将显示第二个绘图中更新的源数据。运行它:bokeh serve --show app.py
from random import random
from bokeh.models import CustomJS, ColumnDataSource, Row
from bokeh.plotting import figure, show, curdoc
from bokeh.models.widgets import Button
x = [random() for x in range(500)]
y = [random() for y in range(500)]
s1 = ColumnDataSource(data = dict(x = x, y = y))
p1 = figure(plot_width = 400, plot_height = 400, tools = "lasso_select", title = "Select Here")
p1.circle('x', 'y', source = s1, alpha = 0.6)
s2 = ColumnDataSource(data = dict(x = [], y = []))
p2 = figure(plot_width = 400, plot_height = 400, x_range = (0, 1), y_range = (0, 1), tools = "", title = "Watch Here")
p2.circle('x', 'y', source = s2, alpha = 0.6)
s1.selected.js_on_change('indices', CustomJS(args = dict(s1 = s1, s2 = s2), code = """
var inds = cb_obj.indices;
var d1 = s1.data;
d2 = {'x': [], 'y': []}
for (var i = 0; i < inds.length; i++) {
d2['x'].push(d1['x'][inds[i]])
d2['y'].push(d1['y'][inds[i]])
}
s2.data = d2 """))
def get_values():
print(s2.data)
button = Button(label = "Get selected set")
button.on_click(get_values)
curdoc().add_root(Row(p1, p2, button))
在您的示例中未更新源数据,因为JS中没有用于检测推送更改的机制。只能检测到为source.data
分配新对象。一旦检测到更改,就可以同步BokehJS和Python模型之间的数据。