Get actual selected value contained within SELECTmodel in Bokeh

Hello,

I’m using bokeh for reasearch purpose, I find it very useful and interesting, the problem is that I use multi-select model with scatter plot in Jupyter Notebook, and I want to get the selected value in python variable each time i update it in the select widget, I tried with IPython.notebook.kernel in the custom JS call back and it doesn’t work. This is my complete code and I’m seeking then for you help :

requetes = pd.read_csv('req_bokeh.csv', index_col=[0])
x = list(requetes['nbLignes'])
y = list(requetes['durationMS'])
instance = list(requetes['instanceCode'])
declination = list(requetes['DeclinaisonCOP'])

    s1 = ColumnDataSource(data=dict(x=x, y=y, instance = instance, declination = declination))

    p1 = figure(plot_width=800, plot_height=400, tools="lasso_select, box_select, pan, zoom_in, zoom_out, reset", title="Queries",tooltips=[("instance :", "@instance"), ("declination :", "@declination")])

    p1.circle('x', 'y', source=s1, alpha=0.6)

    declination_list = ['All'] + list(requetes['DeclinaisonCOP'].unique())
    instance_list = ['All'] + list(requetes['instanceCode'].unique())

    controls = {
        "declination": Select(title="Declination", value="All", options=declination_list),
        "instance": Select(title="Instance", value="All", options=instance_list)
    }
    controls_array = controls.values()
    callback = CustomJS(args=dict(source=s1, controls=controls), code="""
        if (!window.full_data_save) {
            window.full_data_save = JSON.parse(JSON.stringify(source.data));
        }
        var full_data = window.full_data_save;
        var full_data_length = full_data.x.length;
        var new_data = { x: [], y: [], instance: [], declination : []}
        for (var i = 0; i < full_data_length; i++) {
            if (full_data.declination[i] === null)
                continue;
            if (
                (controls.declination.value === 'All' || full_data.declination[i] === controls.declination.value) && 
                (controls.instance.value === 'All' || full_data.instance[i] === controls.instance.value)
            ) {
                Object.keys(new_data).forEach(key => new_data[key].push(full_data[key][i]));
            }
        }
        source.data = new_data;
        source.change.emit();
        var kernel = IPython.notebook.kernel;
        kernel.execute("selected_value = " + controls.declination.value)
    """)

    for single_control in controls_array:
        single_control.js_on_change('value', callback)    

    inputs_column = column(*controls_array)
    layout = column(inputs_column, p1)
    output_notebook()
    show(layout)

I got this result

the select widget works fine, the customJS too, the only problem is that i want to get the value in the select widget in Python variable, thank you

There may be some workable solution with kernel.execute but I would l regard any such approach as clunky/hacky at best and would not recommend it. If you need JS → Python synchronization, the best solution is to embed a Bokeh server app in the notebook, as shown in this example:

bokeh/notebook_embed.ipynb at branch-2.4 · bokeh/bokeh · GitHub

There is also some very recent work around integrating with ipywidgets directly, but it may still have issues to work out, YMMV:

bokeh/examples/howto/ipywidgets at branch-2.4 · bokeh/bokeh · GitHub

Thank you that was very helpful when using Bokeh server app in the notebook, I can now acces easily to my variables