触发"点按"在Bokeh中使用AutocompleteInput的值

时间:2017-02-28 22:13:40

标签: bokeh

我使用来自熊猫数据帧(df)的Bokeh制作一些数据的散点图。数据框是大学数据,并且有专栏" faculty_salary","学费"," sector"和" institution_name"。该图是教师与学费的比较,我使用该部门为数据着色,如下所示。

enter image description here

我目前使用点按工具会将除了您点击的数据点以外的所有其他数据点灰化,如下所示。  enter image description here

我想要做的是使用AutocompleteInput小部件从自动完成中选择一个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中的选定值突出显示它对应的数据点。我应该注意,对于我的应用程序,我更喜欢CustomJS解决方案,而不是Bokeh服务器解决方案。

编辑:事实证明我的浏览器(Linux中的Chrome)并未识别出已选择自动完成值,但Firefox for Linux确实如此。我认为这一定是因为Jquery UI说:

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

欢迎提出如何在Bokeh中解决这个问题的建议。

1 个答案:

答案 0 :(得分:2)

以下是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)