How to maintain selection when filtering?

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)