【发布时间】:2019-05-23 09:10:53
【问题描述】:
我使用以前的帖子here 和here 尝试运行代码,借此我可以在 Bokeh 的 DataTable 中选择一行,并获取行号。但是我发现使用该代码,一旦我超过第 6 行或第 7 行,生成的行号是错误的 - 例如,我可以单击第 17 行,它会说它是第 6 行。我该如何解决这个问题?
请注意this 帖子中的代码,仅当我将“源”ColumnDataSource 中的范围从 10 增加到 20 时才会发生错误。
from random import randint
from datetime import date
from bokeh.models import ColumnDataSource, TableColumn, DateFormatter, DataTable, CustomJS
from bokeh.layouts import column
from bokeh.models.widgets import TextInput
from bokeh.plotting import curdoc
source = ColumnDataSource(dict(dates = [date(2014, 3, i + 1) for i in range(20)], downloads = [randint(0, 100) for i in range(20)]))
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)
text_row = TextInput(value = None, title = "Row index:", width = 420)
text_column = TextInput(value = None, title = "Column Index:", width = 420)
text_date = TextInput(value = None, title = "Date:", width = 420)
text_downloads = TextInput(value = None, title = "Downloads:", width = 420)
test_cell = TextInput(value = None, title = "Cell Contents:", width = 420)
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 }
}
}
text_row.value = String(row);
text_column.value = String(column);
text_date.value = String(new Date(source.data['dates'][row]));
text_downloads.value = String(source.data['downloads'][row]);
test_cell.value = column == 1 ? text_date.value : text_downloads.value; """
def py_callback(attr, old, new):
print(test_cell.value)
print(text_date.value)
source.selected.update(indices = [])
source.selected.on_change('indices', py_callback)
callback = CustomJS(args = dict(source = source, text_row = text_row, text_column = text_column, text_date = text_date, text_downloads = text_downloads, test_cell = test_cell), code = source_code)
source.selected.js_on_change('indices', callback)
curdoc().add_root(column(data_table, text_row, text_column, text_date, text_downloads, test_cell))
我附上了运行代码时遇到的错误的图片。你可以 我点击了第 16 行,它说的是第 10 行。
或者我的其他代码(引用我已经从本地工作服务器上的数据创建的许多不同的数据框等):
import pandas as pd
pd.options.mode.chained_assignment = None
import datetime as dt
import math
import random
import pandas as pd
import itertools
import pickle
from bokeh.layouts import layout
from collections import OrderedDict
from bokeh.models import ColumnDataSource, Column, TableColumn, DateFormatter, DataTable, CustomJS, DataRange1d
from bokeh.plotting import figure, curdoc
source = ColumnDataSource(dict(products=dfNew['Products'], prices=dfNew['Current Prices']))
columns = [TableColumn(field="products", title="Products"), TableColumn(field="prices", title="Current Prices")]
data_table = DataTable(source=source, columns=columns, width=400, height=350, editable=True, reorderable=False)
location_source = ColumnDataSource(dict(row=[], column=[]))
prodPx = OrderedDict()
pVal = 0
for i in products:
key = str(i)
prodPx[key] = [(dfNew['Current Prices'])[pVal]]
pVal += 1
noProd = OrderedDict()
kVal = 0
for i in products:
key = str(kVal)
noProd[key] = [i]
kVal += 1
prodpx_source = ColumnDataSource(prodPx)
noprod_source = ColumnDataSource(noProd)
#initial chart
x = new_dates
y = df[products[0]]
sourceChart = ColumnDataSource(data=dict(x=x, y=y))
chart = figure(title=ccy + ' Charting', x_axis_type='datetime', plot_width = 1200, plot_height=500)
chart.line('x', 'y', source=sourceChart, line_width=3, line_alpha=0.6)
#callbacks
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]};
}
}
}
source.change.emit();
source2.change.emit();
source3.change.emit();
source4.change.emit();
"""
#js callback
callback = CustomJS(args=dict(source=source, source2=location_source, source3=prodpx_source,
source4=noprod_source), code=source_code)
source.selected.js_on_change('indices', callback)
#python callback
def py_callback(attr, old, new):
row = str((location_source.data['row'][0]))
chartVals = (noprod_source.data[row][0])
try:
yVar = df[chartVals]
except:
yVar = df[totalProducts[0]]
sourceChart.data = dict(x=x, y=yVar)
source.selected.update(indices=[])
print(location_source.data)
source.selected.on_change('indices', py_callback)
layout = layout([data_table], [chart])
curdoc().add_root(layout)
【问题讨论】:
-
您需要发布您的代码,否则无法猜测。
-
嗨,Tony - 已从其中一个链接帖子中发布了代码 - 在“源”ColumnDataSource 中已将“for i in range(10)”更改为“for i in range(20)”,并且得到错误。例如。当我点击第 14 行时,生成的“行索引”为 8。
-
抱歉,我要求您发布 您的代码 不起作用,而不是其他帖子中的代码起作用。
-
嗨,托尼 - 很抱歉澄清一下,但我重新发布的另一篇文章中的上述代码(范围(10)到范围(20)的微小变化)对我不起作用。我可以运行它,当点击到第 10 行时它会按预期执行,但之后它吐出的“行”是不正确的。我还在上面发布了我自己的代码,它有同样的问题,但它引用了许多非常长的以前代码中的许多数据帧和变量等,因此无法按原样运行。感谢您的帮助 - 谢谢!
-
Tony - 我添加了运行上述另一篇文章中的代码时发生的情况的屏幕截图,以帮助解释错误。
标签: javascript charts bokeh