我从另一个来源获取了以下代码-这不是我自己的代码。
该代码允许您在数据表中选择一个单元格,并且该单元格的“下载”数据将根据所选单元格的行进行绘制。
如何扩展此代码,以便如果我有多个变量(例如“下载”和“上传”)以及数据表中有更多列,则可以基于该单元格绘制数据(因此,行和列在何处)是重要的)?或者,如何将所选单元格的列号定义为变量(可以使用下面的selected_row来定义行号的方式相同)?
from datetime import date
from random import randint
from bokeh.models import ColumnDataSource, Column
from bokeh.plotting import figure, curdoc
from bokeh.models.widgets import DataTable, DateFormatter, TableColumn, Div
import numpy as np
data = dict(dates = [date(2014, 3, i + 1) for i in range(10)],
downloads = [randint(0, 100) for i in range(10)])
d_source = ColumnDataSource(data)
columns = [TableColumn(field = "dates", title = "Date", formatter = DateFormatter()),
TableColumn(field = "downloads", title = "Downloads")]
data_table = DataTable(source = d_source, columns = columns, width = 400, height = 280)
def table_select_callback(attr, old, new):
selected_row = new[0]
download_count = data['downloads'][selected_row]
chart_data = np.random.uniform(0, 100, size = download_count)
p = figure(title = 'bla')
r = p.line(x = range(len(chart_data)), y = chart_data)
root_layout.children[1] = p
d_source.selected.on_change('indices', table_select_callback)
root_layout = Column(data_table, Div(text = 'Select Date'))
curdoc().add_root(root_layout)
答案 0 :(得分:1)
这是最终的工作代码(使用bokeh serve --show app.py
从命令行运行):
from datetime import date
from random import randint
from bokeh.models import ColumnDataSource, Column, TableColumn, DateFormatter, DataTable, CustomJS
from bokeh.plotting import figure, curdoc
source = ColumnDataSource(dict(dates = [date(2014, 3, i + 1) for i in range(10)], downloads = [randint(0, 100) for i in range(10)]))
columns = [TableColumn(field = "dates", title = "Date", formatter = DateFormatter()), TableColumn(field = "downloads", title = "Downloads")]
data_table = DataTable(source = source, columns = columns, width = 400, height = 280, editable = True, reorderable = False)
info_source = ColumnDataSource(dict(row = [], column = []))
source_code = """
var grid = document.getElementsByClassName('grid-canvas')[0].children;
var row, column = '';
for (var i = 0,max = grid.length; i < max; i++){
if (grid[i].outerHTML.includes('active')){
row = i;
for (var j = 0, jmax = grid[i].children.length; j < jmax; j++)
if(grid[i].children[j].outerHTML.includes('active')) {
column = j;
source2.data = {row: [row], column: [column]};
}
}
}"""
callback = CustomJS(args = dict(source = source, source2 = info_source), code = source_code)
source.selected.js_on_change('indices', callback)
def py_callback(attr, old, new):
source.selected.update(indices = [])
print(info_source.data)
source.selected.on_change('indices', py_callback)
curdoc().add_root(Column(data_table))
答案 1 :(得分:0)
我的建议是使用my another post,它使用JS回调来访问所选单元格的行和列。这必须是JS回调,因为它使用HTML元素进行遍历。因此,步骤如下:
定义一个新的catch
,其中将包含单击的单元格的行号和列号
ColumnDataSource
使用this post中的JS回调在此新info_source = ColumnDataSource(dict(row = [], column = []))
中填写row
和column
值,如下所示:
table_info_source
callback=CustomJS(args=dict(source=d_source,source2=info_source),code=source_code)
在JS回调内部存储source.selected.js_on_change('indices', callback)
和row
索引,如下所示:
column
在Python回调中访问source2.data = {row:[row],column:[column]};
信息以绘制图
info_source.data
两个回调都附加到相同的源,但通常首先执行JS回调,因此数据应按时在Python回调中可用。具有单击单元格的行和列的索引,您应该能够检索所需的数据并绘制图表。