☰Read-only archive⌕
Looking for help with Bokeh?

This is a read-only archive. Ask questions and join the conversation on GitHub.

Visit Community Support on GitHub →
Archived discussions · Captured October 28, 2026

Possible to update lasso selection DataTable with updated CDS data?

Community Supportdatatablecustomjsbokehjsserverbokeh
mkellom
mkellom

Hello,

I have a table that displays CDS data from the plot lasso selection tool indices. If the CDS data gets updated, is there a way to update the table without having to redo the lasso selection? The DataTable gets updated with a CustomJS callback, while the CDS gets updated with a server callback.

source = ColumnDataSource(data=dict(LDA1=dataset_LDA2D.LDA1, 
                                         LDA2=dataset_LDA2D.LDA2,
                                         colors=dataset_LDA2D.color,
                                         map_value=dataset_LDA2D.map_value)

lasso_source = ColumnDataSource(data=dict(LDA1=[],
											LDA2=[],
											colors=[],
											map_value=[]))

tools_ = ['crosshair', 'zoom_in', 'zoom_out', 'save', 'reset', 'tap', 'box_zoom', 'pan', 'undo', 'redo', 'wheel_zoom']

p = figure(tools=tools_, active_drag="box_zoom", width=1800, height=2000)

p1 = p.circle('LDA1', 'LDA2', fill_color='colors',
              size=7, alpha=0.5, line_alpha=0,
              source=source, name='Data')

lasso_1 = LassoSelectTool(continuous=False)
p.add_tools(lasso_1)

lasso_table = DataTable(source=lasso_source, columns=[TableColumn(field='map_value', title="Map Value")], width=600, height=1500, fit_columns=True)

lasso_callback = CustomJS(args=dict(lasso_source=lasso_source, source=source, lasso_table=lasso_table), code="""
    var inds = cb_obj.indices;
    var s1 = source.data;
    var ld = lasso_source.data;
    ld['LDA1'] = [];
    ld['LDA2'] = [];
    ld['colors'] = [];
    ld['map_value'] = [];
    for (var i = 0; i < inds.length; i++) {
        ld['LDA1'].push(s1['LDA1'][inds[i]]);
        ld['LDA2'].push(s1['LDA2'][inds[i]]);
        ld['colors'].push(s1['colors'][inds[i]]);
        ld['map_value'].push(s1['map_value'][inds[i]]);
    }
    lasso_source.change.emit();
    lasso_table.change.emit();
""")

source.selected.js_on_change('indices', lasso_callback)

heat_slider = Slider(start=1, end=4, value=1, step=1, title="Heat")

def marker_callback(attr, old, new):
   path = '/myapp/data/'+directory+'/'+product_file+'.db'
   con = sqlite3.connect(path)
   query = 'SELECT * FROM '+product_file
   product_df = pd.read_sql_query(query, con)
   con.close()
   if(heat_slider.value == 1):
		source.data['map_value'] = product_df.product_values1.to_list()
   elif(heat_slider.value == 2):
		source.data['map_value'] = product_df.product_values2.to_list()
   elif(heat_slider.value == 3):
		source.data['map_value'] = product_df.product_values3.to_list()
   elif(heat_slider.value == 4):
		source.data['map_value'] = product_df.product_values4.to_list()

heat_slider.on_change('value', marker_callback)
⌁   Link to post
Bryan
Bryan

If the CDS data gets updated, is there a way to update the table without having to redo the lasso selection?

No, hit-testing for selections only happens when the lasso is “completed” (i.e. the user raises the mouse button and the drag event stops) There is not currently any exposed, user-facing API for programmatically performing hit-testing. At best you can clear the selection when the data changes.

Edit: well, in principle you could register a callback for the SelectionGeometry event that saves the lasso geometry somewhere between events, and then do your own hit-testing against the saved geometry, in order to set the selection manually whenever the data changes. I don’t have any example code or anything to share, though, all I can offer is the outline above.

⌁   Link to post
gmerritt123
gmerritt123

Maybe I’m not interpreting the question properly, but could they not trigger an update/table redraw by storing the selected indices in a variable in marker_callback and then toggle source.selected.indices to an empty list then back to the stored indices to trigger lasso_callback?

e.g.

def marker_callback(attr,old,new):
    sel_inds = source.selected.indices #grab current selection
    #.... DO STUFF/UPDATE source data
   source.selected.indices = [] 
   source.selected.indices = sel_inds



⌁   Link to post
Bryan
Bryan

My assumption was that the new data could have new positions and/or a different number of rows in the CDS, meaning that the the previous selection indices would no longer be valid in any meaningful way.

The approach above only seems reasonable to me under the strict assumption that the new data in the CDS has exactly the same number of rows and all the points have exactly the same coordinates. Otherwise the previous indices could be out of bounds with respect to the new data, or indices for previously selected points now refer to new points that are now not contained inside the lasso.

⌁   Link to post
mkellom
mkellom

Ah yes, sorry my post was not more clear. In this case, the x-y coordinates would always be the same when changing the CDS data. Only the “map_value” would change, which is just a data annotation that is displayed in the table.

⌁   Link to post

End of archived discussion · Replies are disabled