我使用ColumnDataSource在散点图中绘制了一堆数据,一列是X坐标,另一列是Y坐标。第三列的患者ID可能有重复。我想创建一个Tap派生工具,它将选择在患者ID列中共享相同值的所有其他x,y坐标。
'x' 'y' 'ID'
1 2 'p1'
2 3 'p1'
2 5 'p2'
0 1 'p2'
所以基本上如果我在我的散景散点图中点击坐标(1,2),我会得到(1,2)和(2,3)点的选择,而其他所有选择都未被选中,就像你如何找到套索和boxselect工具表现。
答案 0 :(得分:5)
以下是使用带有散景0.12.6的CustomJS的示例解决方案。基本上当用户选择一个字形时,你知道哪一行对应。查找关联的id值,然后将具有相同id的所有其他数据点添加到ColumnDataSource的selected属性。
您也可以仅使用python创建等效回调。但是,这将需要使用散景服务器。代码也非常相似。
from bokeh.plotting import figure, output_file, show
from bokeh.models import ColumnDataSource, CustomJS
# output to static HTML file
output_file("line.html")
p = figure(plot_width=400, plot_height=400,tools=["tap"])
x =[1,2,2,0]
y = [2,3,5,1]
n_id = ['p1','p1','p2','p2']
data = {'x':x,'y':y,'id':n_id}
source = ColumnDataSource(data)
# source callback
code = """
var data = source.data,
selected = source.selected['1d']['indices'],
select_inds = [selected[0]];
if(selected.length == 1){
// only consider case where one glyph is selected by user
selected_id = data['id'][selected[0]]
for (var i = 0; i < data['x'].length; ++i){
if(data['id'][i] == selected_id){
// add all points to selected if their ids coincide with original
// glyph that was clicked.
select_inds.push(i)
}
}
}
source.selected['1d']['indices'] = select_inds
source.change.emit();
"""
callback = CustomJS(args={'source':source},code=code)
source.callback=callback
p.circle('x','y',source=source, size=20, color="navy", alpha=0.5)
# show the results
show(p)
在最近的散景版本中,用于访问所选索引的符号已经有所简化。为了与bokeh 0.13.0兼容,JS回调可能变为:
code = """
var data = source.data,
selected = source.selected.indices,
select_inds = [];
if(selected.length == 1){
// only consider case where one glyph is selected by user
selected_id = data['id'][selected[0]]
for (var i = 0; i < data['x'].length; ++i){
if(data['id'][i] == selected_id){
// add all points to selected if their ids coincide with original
// glyph that was clicked.
select_inds.push(i)
}
}
}
source.selected.indices = select_inds
source.change.emit();
"""