如何从与Bokeh的CustomJS函数的局部变量同步的ColumnDataSource对象获取数据? [英] How can I get data from a ColumnDataSource object which is synchronized with local variables of Bokeh's CustomJS function?
问题描述
基于以下代码示例,我想在CustomJS函数中提取数据(例如x值)以将其保存在python列表rect_data
中.尽管变量x与ColumnDataSource对象source
同步,但是当我在下面执行的代码图中绘制矩形选择时,python列表rect_data
仍为空列表.我在做什么错,我该如何解决这个问题?
Based on the following code sample, I want to extract the data (for example the x value) in the CustomJS function to save it in the python list rect_data
. Although the variable x is synchronized with the ColumnDataSource object source
, the python list rect_data
remains an empty list when I draw a rectangular selection in the figure of the executed code below. What am I doing wrong and how can I solve this problem?
提前谢谢!
# You must first run "bokeh serve" to view this example
from bokeh.models import CustomJS, ColumnDataSource, BoxSelectTool, Range1d, Rect
from bokeh.plotting import figure, show
from bokeh.client import push_session
from bokeh.io import curdoc
source = ColumnDataSource(data=dict(x=[], y=[], width=[], height=[]))
callback = CustomJS(args=dict(source=source), code="""
var data = source.get('data');
var geometry = cb_data['geometry'];
var width = geometry['x1'] - geometry['x0'];
var height = geometry['y1'] - geometry['y0'];
var x = geometry['x0'] + width/2;
var y = geometry['y0'] + height/2;
data['x'].push(x);
data['y'].push(y);
data['width'].push(width);
data['height'].push(height);
source.trigger('change');
""")
box_select = BoxSelectTool(callback=callback)
p = figure(plot_width=400,
plot_height=400,
tools=[box_select],
title="Select Below",
x_range=Range1d(start=0.0, end=1.0),
y_range=Range1d(start=0.0, end=1.0))
rect = Rect(x='x',
y='y',
width='width',
height='height',
fill_alpha=0.3,
fill_color='#009933')
p.add_glyph(source, rect, selection_glyph=rect, nonselection_glyph=rect)
session = push_session(curdoc())
def update():
global rect_data
global source
rect_data = source.data['x']
print(rect_data)
curdoc().add_periodic_callback(update,10)
session.show()
session.loop_until_closed()
推荐答案
您可以将ToolEvents用于此目的.参见下面的示例.
You can use the ToolEvents for this purpose. See example below.
from bokeh.plotting import figure
from bokeh.client import push_session
from bokeh.io import curdoc
from bokeh.models import ColumnDataSource, CustomJS, BoxSelectTool, Range1d, Rect
source = ColumnDataSource(data=dict(x=[], y=[], width=[], height=[]))
callback = CustomJS(args=dict(source=source), code="""
var data = source.get('data');
var geometry = cb_data['geometry'];
var width = geometry['x1'] - geometry['x0'];
var height = geometry['y1'] - geometry['y0'];
var x = geometry['x0'] + width/2;
var y = geometry['y0'] + height/2;
data['x'].push(x);
data['y'].push(y);
data['width'].push(width);
data['height'].push(height);
source.trigger('change');
""")
box_select = BoxSelectTool(callback=callback)
p = figure(plot_width=400,
plot_height=400,
tools=[box_select],
title="Select Below",
x_range=Range1d(start=0.0, end=1.0),
y_range=Range1d(start=0.0, end=1.0))
rect = Rect(x='x',
y='y',
width='width',
height='height',
fill_alpha=0.3,
fill_color='#009933')
p.add_glyph(source, rect, selection_glyph=rect, nonselection_glyph=rect, name="selectionbox")
session = push_session(curdoc())
def toolEventsCallback(attr, old, new):
print("callback", new)
x0 = new[0]['x0']
x1 = new[0]['x1']
print("x0=%f x1=%f" % (x0, x1))
p.tool_events.on_change("geometries", toolEventsCallback)
session.show()
session.loop_until_closed()
至少在Bokeh 0.11.1中,没有针对ColumnDataSource的事件发送回Python.
At least in Bokeh 0.11.1 there are no events send back to Python for the ColumnDataSource.
这篇关于如何从与Bokeh的CustomJS函数的局部变量同步的ColumnDataSource对象获取数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!