如何以编程方式更新选定的源索引?

How to update the selected source indices programmatically?

从文档中,Selection 对象说:

Selections are typically created by selecting points in a plot with a SelectTool, but can also be programmatically specified.

但我不知道如何以编程方式设置一些选定的点。例如,如果我想通过单击某个按钮来更新选择。我可以更新元素source.selected.indices,但事件没有触发,点也没有标记为选中

from bokeh.io import curdoc
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure
from bokeh.layouts import column
from bokeh.models.tools import LassoSelectTool, TapTool
from bokeh.models.widgets.buttons import Button

source = ColumnDataSource(dict(
    x=[1, 2, 3, 4, 5, 6],
    y=[1, 2, 3, 4, 5, 6],
))

p = figure(
    plot_height=300,
    tools='',
)
p.circle( x='x', y='y', size=20, source=source)

lasso_select = LassoSelectTool(
    select_every_mousemove=False,
)
tap = TapTool()
tools = (lasso_select, tap)
p.add_tools(*tools)

def update_selection_programmatically():
    source.selected.update(indices=[4])           # the indices attribute is updated but the figure is not repainted, some event is not triggered.
                                                  # So the points are not marked as selected
bt = Button(
    label="Update Selection",
    button_type="success",
    width=50
)

bt.on_click(update_selection_programmatically)


def update_selection(attr, old, new):
    print('>> NEW SELECTION: {}'.format(new.indices))
    # new.indices = [0]       # this works fine here

source.on_change('selected', update_selection)

curdoc().add_root(column([p, bt]))

索引属性已更新,但图形未重新绘制。

这适用于 CustomJS 回调

bt.callback = CustomJS(args={'source':source},code="""source.selected.indices = [4];source.change.emit();""")

我认为 Python 回调应该自动执行 source.change.emit(),所以不确定为什么你的回调不起作用。 但是您可以在 JS 回调中明确地执行此操作。

我不知道为什么但它不会触发 update_selection

答案更新

最终bokeh开发者解决了这个问题。现在可以使用

更新索引
source.selected.update(indices=[4])

# or equivalently

source.selected.indices = [4]

旧的解决方法

johncthomas wrote a comment in the GitHub issue。有一个解决方法:

I figured out a work around for this

# When this does not update the visible selections 
source.selected.indices = new_indicies

# This causes the selections to be visible
source.data = source.data

Specifically this is when running a server in version 13.0. Obviously not ideal but it worked for me.