如何在 Bokeh.widget.DataTable 中预置 select 行?

How do I pre-select rows in a Bokeh.widget.DataTable?

Bokeh 能够在数据框中显示数据,如下所示:

http://docs.bokeh.org/en/latest/docs/user_guide/interaction/widgets.html#data-table

设置:

我有以下格式的数据框:

Index|Location|Value
-----|--------|-----
1    |1       | 10
2    |1       | 20
3    |1       | 30
4    |2       | 20
5    |2       | 30
6    |2       | 40

此数据框可以显示在数据 table 中,如下所示:

source = ColumnDataSource(data={
    LOCATION_NAME: [],
    VALUE_NAME: []
})

columns = [
    TableColumn(field=LOCATION_NAME, title=LOCATION_NAME),
    TableColumn(field=VALUE_NAME, title=VALUE_NAME)
]

data_table = DataTable(source=source, columns=columns, width=400, height=800)

def update_dt(df):
    """Update the data table. This function is called upon some trigger"""
    source.data = {
        LOCATION_NAME: mt_val_df[LOCATION_NAME],
        VALUE_NAME: mt_val_df[VALUE]}

理想情况下,我希望此数据table 驱动热图,其中为每个位置生成的 select 离子将导致热图中的值发生变化。但是一张热图不能在一个位置有多个值。我也不知道如何在数据 table.

中预先 select 项目

假设我有第二个数据框:

Index|Location|Value
-----|--------|-----
2    |1       | 20
6    |2       | 40

此数据框代表上述 table 的一个子集 - 可能是上述的一些自定义 selection。

问题:

在最基本的层面上:我有我的 selection 行的索引。我如何根据第二个数据帧的行在上面的数据 table 中 highlight/pre-select 行?

更新(2017-07-14):到目前为止,我尝试在数据源python端设置selected索引。尽管 source['selected']['1d'].indices = [LIST OF MY SELECTION] 确实正确设置了索引,但我没有在 Bokeh 0.12.5 的前端 DataTable 上看到相应的更新。

我也试过在前端设置索引。我的问题是我不知道如何通过 CustomJS 传递与 Bokeh 无关的参数。

更完整的级别:select数据中的离子table如何驱动热图?

更新(2017-07-17):我还没有得到在 Bokeh 应用程序的上下文中工作的建议解决方案! 我目前正试图找出原因,但要弄清楚为什么最终没有 selected 有点棘手。我怀疑代码字符串在页面加载时开始实例化。然而,我的坐标直到后来才计算出来。因此,点击带有回调的按钮会导致 selection 变为空 - 即使后来 selection 行已被计算。将不胜感激!

感谢 Claire Tang 和 Bryan Van de ven 的有益评论,我找到了上述问题的部分答案 here

关于数据表中未显示预选

据我所知,这是由两个问题引起的。

1.) 如果我在 CustomJS 中更新了选定的索引列表,我就没有在 DataTable 中注册更改。

button.callback = CustomJS(args=dict(source2=source2), code="""
source2.selected['1d'].indices = [1,2,3];
//I did not "emit" my changed selection in the line below.
source2.properties.selected.change.emit();
console.log(source2)
""")  

2.) 另一个需要注意的重要方面是我使用的是 Bokeh 版本 0.12.5。在此版本中,"source2.properties.selected" 是一个未知的 属性(可能是因为此功能位于其他地方或尚未实现)。因此,只要我留在 Bokeh 0.12.5 上,选择对我来说也会失败。对 Bokeh 0.12.6 的更新和上面的行使选择能够出现在 DataTable 上。

关于来自 Jupyter Notebook 的动态输入

以上示例展示了我如何使用按钮和链接的 CustomJS 回调来触发硬编码列表的选择。问题是如何根据一些更动态的计算输入索引值列表,因为 CustomJS 不允许使用与 Bokeh 无关的外部参数。关于这个主题,因为 CustomJS "code" 属性只需要一个字符串。我尝试了以下方法:

dynamically_calculated_index = [1,2,3]
button.callback = CustomJS(args=dict(source1=source1, source2=source2), code="""
source2.selected['1d'].indices = {0};
source2.properties.selected.change.emit();
console.log(source2)
""".format(dynamically_calculated_index)) 

我不确定这是否是最佳做法,因此我欢迎在这方面提供反馈,但目前这对我有用。正如@DuCorey 所指出的,一旦 these changes 位于散景的主要分支中,我的问题的一些排列可以更容易地解决,如 him/her.

所述

此外:此方法仅适用于 Jupyter Notebook,其中整个单元会再次重新计算,并且任何预先计算的选定索引都会在单元执行时绑定。我可以添加一个静态列表,它适用于此,但如果我想动态计算上面的列表,它将不起作用。我仍然需要找到解决方法。

解决上述问题现在让我可以专注于将所选内容的更改传播到热图。

使用 Bokeh 服务器的最终答案

这里的答案很简单:可以更改所选项目,但必须按以下方式完成:

ds.selected = {'0d': {'glyph': None, 'indicices': []},
               '1d': {indices': selected_index_list},
               '2d': {}}

以前,我只尝试替换 1d 索引,但由于某些未知原因,我实际上必须替换整个选定字典,以便 bokeh 应用程序注册选定索引的更改。所以不要只做:

ds.selected['1d']['indices'] = selected_index_list

现在这对我有用。不过,如果您能从更有见识的人那里得到解释,我们将不胜感激。

我设法预先select使用这个

    resultPath = "path/to/some/file.tsv"
    resultsTable = pandas.read_csv(resultPath,sep="\t")
    source = ColumnDataSource(data=resultsTable)
    source.selected.indices = [0,1,2,3,4]  # KEY LINE
    table = DataTable(source=source)