散景数据表中点击选择的图表

时间:2019-05-03 07:16:32

标签: python bokeh

我从另一个来源获取了以下代码-这不是我自己的代码。

该代码允许您在数据表中选择一个单元格,并且该单元格的“下载”数据将根据所选单元格的行进行绘制。

如何扩展此代码,以便如果我有多个变量(例如“下载”和“上传”)以及数据表中有更多列,则可以基于该单元格绘制数据(因此,行和列在何处)是重要的)?或者,如何将所选单元格的列号定义为变量(可以使用下面的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)

2 个答案:

答案 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元素进行遍历。因此,步骤如下:

  1. 定义一个新的catch,其中将包含单击的单元格的行号和列号

    ColumnDataSource

  2. 使用this post中的JS回调在此新info_source = ColumnDataSource(dict(row = [], column = []))中填写rowcolumn值,如下所示:

table_info_source
 callback=CustomJS(args=dict(source=d_source,source2=info_source),code=source_code)

  1. 在JS回调内部存储source.selected.js_on_change('indices', callback)row索引,如下所示:

    column

  2. 在Python回调中访问source2.data = {row:[row],column:[column]};信息以绘制图

    info_source.data

两个回调都附加到相同的源,但通常首先执行JS回调,因此数据应按时在Python回调中可用。具有单击单元格的行和列的索引,您应该能够检索所需的数据并绘制图表。