Skip to content Skip to sidebar Skip to footer

How Do I Pre-select Rows In A Bokeh.widget.datatable?

Bokeh has the ability to display data in a dataframe as shown here: http://docs.bokeh.org/en/latest/docs/user_guide/interaction/widgets.html#data-table The Setup: I have a datafram

Solution 1:

I have found a partial answer to the above questions thanks to the helpful comments of Claire Tang and Bryan Van de ven here.

Concerning Pre-selection not showing up on the DataTable

This turns out to be caused be two issues as far as I am aware.

1.) If I updated the selected index list in a CustomJS, I was missing to register the changes in the DataTable.

button.callback = CustomJS(args=dict(source2=source2), code="""
source2.selected['1d'].indices = [1,2,3];
//I did not "emit" my changed selection in the line below.
source2.properties.selected.change.emit();
console.log(source2)
""")  

2.) The other important aspect to note is that I was on Bokeh version 0.12.5. In this version "source2.properties.selected" is an unknown property (perhaps because this function is located somehwhere else or not implemented yet). Therefore, selection also failed for me as long as I remained on Bokeh 0.12.5. An update to Bokeh 0.12.6 and the above line enabled selections to appear on the DataTable.

Concerning dynamic input from a Jupyter Notebook

The above example shows how I can use a button and a linked CustomJS callback to trigger selection of hard-coded lists. The question is how to feed in a list of index values based on some more dynamic calculations because CustomJS does not allow for external parameters that are not Bokeh related. On this topic, since CustomJS "code" attribute just takes a string. I tried the following:

dynamically_calculated_index = [1,2,3]
button.callback = CustomJS(args=dict(source1=source1, source2=source2), code="""
source2.selected['1d'].indices = {0};
source2.properties.selected.change.emit();
console.log(source2)
""".format(dynamically_calculated_index)) 

I am not sure if this is best practice, and so I welcome feedback in this regard, but this works for me for now. As pointed out by @DuCorey, once these changes are in the main branch of bokeh, some permutations of my issue could be more easily solved as described by him/her.

Also: This approach only works for a Jupyter Notebook where the entire cell gets recomputed again, and any pre-computed selected indices get bound at cell execution time. I can add a static list and it works for that, but if I want to dynamically calculate the above list, it will not work. I need to find a workaround still.

Solving the above issues now allows me to concentrate on propagating changes in what is selected to a heatmap.

Final answer using Bokeh server

The answer here was rather simple: It is possible to change the selected items, but it has to be done in the following way:

ds.selected = {'0d': {'glyph': None, 'indicices': []},
               '1d': {indices': selected_index_list},
               '2d': {}}

Previously, I had only tried to replace the 1d indices, but for some unknown reason, I have to actually replace the entire selected dictionary for the change in selected index to be registered by the bokeh app. So don't just do:

ds.selected['1d']['indices'] = selected_index_list

This now works for me. An explanation from someone more knowledgable would be appreciated though.

Solution 2:

I managed to pre-select using this

    resultPath = "path/to/some/file.tsv"
    resultsTable = pandas.read_csv(resultPath,sep="\t")
    source = ColumnDataSource(data=resultsTable)
    source.selected.indices = [0,1,2,3,4]  # KEY LINE
    table = DataTable(source=source)

Post a Comment for "How Do I Pre-select Rows In A Bokeh.widget.datatable?"