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应用程序的上下文中工作! 我目前正试图找到因为但是为什么最后没有选择任何东西有点棘手。我怀疑代码字符串是在页面加载时在开头实例化的。但是,我的坐标直到稍后才计算出来。因此,点击带回调的按钮会导致无选择 - 即使稍后计算了行选择。将继续提供帮助!
答案 0 :(得分:0)
由于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上。
以上示例显示了如何使用按钮和链接的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笔记本,其中整个单元格再次重新计算,并且任何预先计算的选定索引在单元格执行时受到约束。我可以添加一个静态列表,它适用于此,但如果我想动态计算上面的列表,它将无法正常工作。我还需要找到一种解决方法。
现在解决上述问题可以让我专注于将所选内容的变化传播到热图。
这里的答案很简单:可以更改所选项目,但必须按以下方式完成:
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)