The jumping selection is because you change the set of points but the s1.selected.indices
stays the same, I think.
In any case, this is how I’d do it:
from random import random
from bokeh.layouts import layout
from bokeh.models import ColumnDataSource, CustomJS, RangeSlider, CDSView, CustomJSFilter
from bokeh.plotting import figure, curdoc
p1 = figure(plot_width=400, plot_height=400, tools="lasso_select", title="Select Here")
from bokeh.models import DataTable, TableColumn
ds = ColumnDataSource(data=dict(x=[random() for x in range(1_000)],
y=[random() for y in range(1_000)]))
x_slider = RangeSlider(title='X', start=0, end=1, value=(0, 1), step=0.01)
slider_filter = CustomJSFilter(args=dict(slider=x_slider),
# language=JavaScript
code="""
const [min_x, max_x] = slider.value;
return source.data['x'].reduce((acc, x, idx) => {
if (x >= min_x && x <= max_x) acc.push(idx);
return acc
}, [])
""")
x_slider.js_on_change('value', CustomJS(args=dict(ds=ds), code="ds.change.emit();"))
selection_filter = CustomJSFilter(code="return source.selected.indices;")
ds.selected.js_on_change('indices', CustomJS(args=dict(ds=ds), code="ds.change.emit();"))
circle_view = CDSView(source=ds, filters=[slider_filter])
p1.circle('x', 'y', source=ds, view=circle_view, alpha=0.6)
table_view = CDSView(source=ds, filters=[slider_filter, selection_filter])
columns = [
TableColumn(field="x", title='x'),
TableColumn(field="y", title='y'),
]
data_table = DataTable(source=ds, columns=columns, view=table_view)
layout = layout([p1, data_table], x_slider)
doc = curdoc()
doc.add_root(layout)