如何预先选择Bokeh.widget.DataTable中的行?

时间:2017-07-07 00:59:25

标签: python bokeh

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

http://bokeh.pydata.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

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

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]}

理想情况下,我希望此数据表能够驱动热图,其中为每个位置进行的选择将导致热图中的值发生更改。但是热图不能为一个位置提供多个值。我也不知道如何预先选择数据表中的项目。

假设我有第二个数据帧:

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

此数据框代表上表的一个子集 - 可能是上面的一些自定义选择。

问题:

在最基本的层面:我有我选择行的索引。如何根据第二个数据帧的行突出显示/预先选择上面数据表中的行?

更新(2017-07-14):到目前为止,我尝试在数据源python端设置所选索引。虽然源['选择'] [' 1d'] .index = [我的选择列表]确实正确设置了索引,但我没有在前端DataTable上看到相应的更新在Bokeh 0.12.5。

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

更完整的级别:数据表中的选择如何驱动热图?

更新(2017-07-17): 我还没有得到建议的解决方案在Bokeh应用程序的上下文中工作! 我目前正试图找到因为但是为什么最后没有选择任何东西有点棘手。我怀疑代码字符串是在页面加载时在开头实例化的。但是,我的坐标直到稍后才计算出来。因此,点击带回调的按钮会导致无选择 - 即使稍后计算了行选择。将继续提供帮助!

2 个答案:

答案 0 :(得分:0)

由于Claire Tang和Bryan Van de ven here的有用评论,我找到了对上述问题的部分答案。

关于预选择未显示在DataTable上

据我所知,这导致了两个问题。

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笔记本的动态输入

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

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成为散景的主要分支,我的问题的一些排列可以更容易地解决,如他/她所描述的那样。

此外:此方法仅适用于Jupyter笔记本,其中整个单元格再次重新计算,并且任何预先计算的选定索引在单元格执行时受到约束。我可以添加一个静态列表,它适用于此,但如果我想动态计算上面的列表,它将无法正常工作。我还需要找到一种解决方法。

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

使用Bokeh服务器的最终答案

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

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

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

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

现在这对我有用。不过,对于更有知识的人的解释将会受到赞赏。

答案 1 :(得分:0)

我设法使用

进行了预选
    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)