不点击 header 触发 ('change') 后 Bokeh DataTable 不会更新
Bokeh DataTable won't update after trigger('change') without clicking on header
散景版本:0.10
Python:3.4
木星:4.x
目标:创建一个 table 仅显示从散点图中选择的数据
问题:数据表只有在被点击后才会自行刷新
尽管:s2.trigger('change')。在 Bokeh 网站上的其他示例中
plot 将使用此技术更新另一个:请参阅 http://docs.bokeh.org/en/latest/docs/user_guide/interaction.html#customjs-for-selections
如果您使用上述版本,下面的代码应该 运行 在 Jupyter 笔记本中。
并且,感谢您的帮助。
乔
from bokeh.io import output_notebook, show
from bokeh.plotting import figure
from bokeh.models import CustomJS, ColumnDataSource
from bokeh.models.widgets import DataTable, TableColumn
from bokeh.io import vform
output_notebook()
x = list(range(-20, 21))
y0 = [abs(xx) for xx in x]
# create a column data source for the plots to share
source = ColumnDataSource(data=dict(x=x, y0=y0))
s2 = ColumnDataSource(data=dict(x=[1],y0=[2]))
source.callback = CustomJS(args=dict(s2=s2), code="""
var inds = cb_obj.get('selected')['1d'].indices;
var d1 = cb_obj.get('data');
var d2 = s2.get('data');
d2['x'] = []
d2['y0'] = []
for (i = 0; i < inds.length; i++) {
d2['x'].push(d1['x'][inds[i]])
d2['y0'].push(d1['y0'][inds[i]])
}
s2.trigger('change');
""")
# create DataTable
columns = [
TableColumn(field="x", title="x"),
TableColumn(field="y0", title="y0"),
]
dt = DataTable(source=s2, columns=columns, width=300, height=300 )
# create a new plot and add a renderer
TOOLS = "box_select,lasso_select,help"
left = figure(tools=TOOLS, width=300, height=300)
left.circle('x', 'y0', source=source)
show(vform(left,dt))
CustomJS
只触发了s2变化,所以dt没有变化是正常的。
这样就可以了,dt移到JS上面,dt传入JS,触发dt:
dt = DataTable(source=s2, columns=columns, width=300, height=300 )
source.callback = CustomJS(args=dict(s2=s2, dt=dt), code="""
var inds = cb_obj.get('selected')['1d'].indices;
var d1 = cb_obj.get('data');
var d2 = s2.get('data');
d2['x'] = []
d2['y0'] = []
for (i = 0; i < inds.length; i++) {
d2['x'].push(d1['x'][inds[i]])
d2['y0'].push(d1['y0'][inds[i]])
}
console.log(dt);
s2.trigger('change');
dt.trigger('change');
""")
如果您只关心更新 table,那么您实际上不需要同时传递数据源和 "data table"。这是因为 "data table" 已经将来源作为属性。这是完整的代码(注意只传递了 "dt"):
from bokeh.io import output_notebook, show
from bokeh.plotting import figure
from bokeh.models import CustomJS, ColumnDataSource
from bokeh.models.widgets import DataTable, TableColumn
from bokeh.io import vform
output_notebook()
x = list(range(-20, 21))
y0 = [abs(xx) for xx in x]
# create a column data source for the plots to share
source = ColumnDataSource(data=dict(x=x, y0=y0))
s2 = ColumnDataSource(data=dict(x=[1],y0=[2]))
# create DataTable
columns = [
TableColumn(field="x", title="x"),
TableColumn(field="y0", title="y0"),
]
dt = DataTable(source=s2, columns=columns, width=300, height=300 )
# create a new plot and add a renderer
TOOLS = "box_select,lasso_select,help"
left = figure(tools=TOOLS, width=300, height=300)
left.circle('x', 'y0', source=source)
source.callback = CustomJS(args=dict(mytable=dt), code="""
var inds = cb_obj.get('selected')['1d'].indices;
var d1 = cb_obj.get('data');
var d2 = mytable.get('source').get('data');
d2['x'] = []
d2['y0'] = []
for (i = 0; i < inds.length; i++) {
d2['x'].push(d1['x'][inds[i]])
d2['y0'].push(d1['y0'][inds[i]])
}
mytable.trigger('change');
""")
show(vform(left,dt))
散景版本:0.10 Python:3.4 木星:4.x
目标:创建一个 table 仅显示从散点图中选择的数据
问题:数据表只有在被点击后才会自行刷新 尽管:s2.trigger('change')。在 Bokeh 网站上的其他示例中 plot 将使用此技术更新另一个:请参阅 http://docs.bokeh.org/en/latest/docs/user_guide/interaction.html#customjs-for-selections
如果您使用上述版本,下面的代码应该 运行 在 Jupyter 笔记本中。
并且,感谢您的帮助。 乔
from bokeh.io import output_notebook, show
from bokeh.plotting import figure
from bokeh.models import CustomJS, ColumnDataSource
from bokeh.models.widgets import DataTable, TableColumn
from bokeh.io import vform
output_notebook()
x = list(range(-20, 21))
y0 = [abs(xx) for xx in x]
# create a column data source for the plots to share
source = ColumnDataSource(data=dict(x=x, y0=y0))
s2 = ColumnDataSource(data=dict(x=[1],y0=[2]))
source.callback = CustomJS(args=dict(s2=s2), code="""
var inds = cb_obj.get('selected')['1d'].indices;
var d1 = cb_obj.get('data');
var d2 = s2.get('data');
d2['x'] = []
d2['y0'] = []
for (i = 0; i < inds.length; i++) {
d2['x'].push(d1['x'][inds[i]])
d2['y0'].push(d1['y0'][inds[i]])
}
s2.trigger('change');
""")
# create DataTable
columns = [
TableColumn(field="x", title="x"),
TableColumn(field="y0", title="y0"),
]
dt = DataTable(source=s2, columns=columns, width=300, height=300 )
# create a new plot and add a renderer
TOOLS = "box_select,lasso_select,help"
left = figure(tools=TOOLS, width=300, height=300)
left.circle('x', 'y0', source=source)
show(vform(left,dt))
CustomJS
只触发了s2变化,所以dt没有变化是正常的。
这样就可以了,dt移到JS上面,dt传入JS,触发dt:
dt = DataTable(source=s2, columns=columns, width=300, height=300 )
source.callback = CustomJS(args=dict(s2=s2, dt=dt), code="""
var inds = cb_obj.get('selected')['1d'].indices;
var d1 = cb_obj.get('data');
var d2 = s2.get('data');
d2['x'] = []
d2['y0'] = []
for (i = 0; i < inds.length; i++) {
d2['x'].push(d1['x'][inds[i]])
d2['y0'].push(d1['y0'][inds[i]])
}
console.log(dt);
s2.trigger('change');
dt.trigger('change');
""")
如果您只关心更新 table,那么您实际上不需要同时传递数据源和 "data table"。这是因为 "data table" 已经将来源作为属性。这是完整的代码(注意只传递了 "dt"):
from bokeh.io import output_notebook, show
from bokeh.plotting import figure
from bokeh.models import CustomJS, ColumnDataSource
from bokeh.models.widgets import DataTable, TableColumn
from bokeh.io import vform
output_notebook()
x = list(range(-20, 21))
y0 = [abs(xx) for xx in x]
# create a column data source for the plots to share
source = ColumnDataSource(data=dict(x=x, y0=y0))
s2 = ColumnDataSource(data=dict(x=[1],y0=[2]))
# create DataTable
columns = [
TableColumn(field="x", title="x"),
TableColumn(field="y0", title="y0"),
]
dt = DataTable(source=s2, columns=columns, width=300, height=300 )
# create a new plot and add a renderer
TOOLS = "box_select,lasso_select,help"
left = figure(tools=TOOLS, width=300, height=300)
left.circle('x', 'y0', source=source)
source.callback = CustomJS(args=dict(mytable=dt), code="""
var inds = cb_obj.get('selected')['1d'].indices;
var d1 = cb_obj.get('data');
var d2 = mytable.get('source').get('data');
d2['x'] = []
d2['y0'] = []
for (i = 0; i < inds.length; i++) {
d2['x'].push(d1['x'][inds[i]])
d2['y0'].push(d1['y0'][inds[i]])
}
mytable.trigger('change');
""")
show(vform(left,dt))