在 Bokeh 中使用 AutocompleteInput 的值触发 "tap"

Trigger a "tap" using value of AutocompleteInput in Bokeh

我正在使用 pandas 数据帧 (df) 中的 Bokeh 绘制一些数据的散点图。数据框是大学数据,有 "faculty_salary"、"tuition"、"sector" 和 "institution_name" 列。该图是 faculty_salary vs 学费,我使用扇区为数据着色,如下所示。

我目前有一个点按工具,可以将除您单击的数据点之外的所有其他数据点显示为灰色,如下所示。

我想做的是使用 AutocompleteInput 小部件从自动完成中 select 一个 institution_name 并让它通过将所有其他数据点变灰来突出显示该数据点,就像点击工具一样。 AutocompleteInput 小部件工作正常,它只是使它突出显示我正在努力弄清楚的数据点的代码。这是我所在的位置:

source = ColumnDataSource(df)
autocomp = AutocompleteInput(completions=df['name'].tolist())
callback = CustomJS(args=dict(source=source), code="""
    what do I put here?? It doesn't seem to have a cb_obj
""")
autocomp.js_on_change('value',callback)

请告诉我如何实现我描述的功能:使用 AutocompleteInput 中的 selected 值突出显示它对应的数据点。我应该注意,对于我的应用程序,我更喜欢 CustomJS 解决方案,而不是 Bokeh 服务器解决方案。

编辑: 结果是我的浏览器(Linux中的Chrome)无法识别自动完成值selected,但 Firefox for Linux 可以。我想这一定是因为 Jquery UI 说:

此小部件以编程方式操作其元素的值,因此当元素的值更改时可能不会触发本机更改事件。

欢迎就如何在 Bokeh 中解决此问题提出建议。

这是 Bokeh 服务器解决方案:

from bokeh.layouts import layout
from bokeh.io import curdoc
from bokeh.models.widgets import AutocompleteInput
from bokeh.models.widgets import (Panel, Tabs, DataTable, TableColumn,
                                  Paragraph, Slider, Div, Button, Select)
from bokeh.plotting import figure, ColumnDataSource
from bokeh.models import HoverTool,TapTool

def update_selected(wttr,old,new):
    a_val = autocomp.value
    names = source.data['names']
    ind = [i for i,x in enumerate(names) if x == a_val]
    source.selected={'0d': {'glyph': None, 'indices': []}, '1d': {'indices': ind}, '2d': {}}


data_dict = {'names':['test2','test3','hello','goodbye'],
           'x':[0,1,2,3], 'y':[10,20,30,40]}   
source = ColumnDataSource(data_dict)
autocomp = AutocompleteInput(completions=['test2','test3','hello','goodbye'])
autocomp.on_change('value',update_selected )
fig = figure(plot_width=400,
             plot_height=400,
             x_axis_label='x',
             y_axis_label='y',
             tools=["pan","hover","box_zoom","reset,save"])

fig.scatter('x','y',source=source)
layout = layout([[fig, autocomp]])
curdoc().add_root(layout)

编辑:这是使用 customJS

的解决方案
from bokeh.layouts import layout
from bokeh.io import curdoc
from bokeh.models.widgets import AutocompleteInput
from bokeh.plotting import figure, ColumnDataSource
from bokeh.models.callbacks import CustomJS

data_dict = {'names':['test2','test3','hello','test3'],
           'x':[0,1,2,3], 'y':[10,20,30,40]}   
source = ColumnDataSource(data_dict)
fig = figure(plot_width=400,
             plot_height=400,
             x_axis_label='x',
             y_axis_label='y',
             tools=["pan","hover","box_zoom","reset,save"])

fig.scatter('x','y',source=source)
autocomp = AutocompleteInput(completions=['test2','test3','hello','goodbye'])
code = """
var autocomplete = cb_obj.value
var names = source.data.names
function getAllIndexes(arr, val) {
    var indexes = [], i;
    for(i = 0; i < arr.length; i++)
        if (arr[i] === val)
            indexes.push(i);
    return indexes;
}
var index = getAllIndexes(names,autocomplete)
source.selected = {'0d':{indices: [0]}, '1d':{indices: index},'2d':{indices: [0]}}
"""

callback = CustomJS(args={'source':source}, code=code)
autocomp.callback = callback
layout = layout([[fig, autocomp]])
curdoc().add_root(layout)