Bokeh RangeSlider 回调问题,source.change.emit() 给出错误 "Cannot read property 'emit' of undefined"
Bokeh RangeSlider callback issue, source.change.emit() gives error "Cannot read property 'emit' of undefined"
我最近开始了一个新项目,需要我在地图上绘制纬度和经度数据。到目前为止,我已经设法绘制出所有内容,但我一直无法为我用来控制绘制哪些数据的范围滑块创建回调函数。
我当前的代码使用 Amstrad2Python 的响应 here 作为其基础。 运行 Amstrad2Python 提供的代码没有给我任何错误。但是,当我尝试 运行 代码时,当我检查 html 图中的控制台输出时,它给我错误“无法读取未定义的 属性 'emit'”。
这是与我使用的实际代码相似的示例代码,它会产生完全相同的错误:
import bokeh.events as bev
import bokeh.layouts as bla
import bokeh.models as bmo
import numpy as np
import pandas as pd
from bokeh.plotting import figure, output_file, show
sample_data = pd.DataFrame(
data=np.array(
[
[1, 12, 21, 15000],
[2, 25, 90, 15500],
[3, 37, 47, 15500],
[4, 41, 56, 15000],
[5, 50, 21, 14500]
]
),
columns=['Seconds', 'lat', 'long', 'alt']
)
#create 2 sources, 1 for editting, 1 for referencing
source = bmo.ColumnDataSource(sample_data) #const data
filtered_source = bmo.ColumnDataSource(sample_data) #alterable data
#create callback function
callback = bmo.CustomJS(args=dict(source=source, filtered_source = filtered_source),
code="""
var data = source.data;
var start = cb_obj.value[0];
var end = cb_obj.value[1];
function generateNewDataObject(oldDataObject){
var newDataObject = {}
for (var key of Object.keys(oldDataObject)){
newDataObject[key] = [];
}
return newDataObject
}
function addRowToAccumulator(accumulator, dataObject, index) {
for (var key of Object.keys(dataObject)){
accumulator[key][index] = dataObject[key][index];
}
return accumulator;
}
var new_data = generateNewDataObject(data);
for (var i = 0; i < source.data['Seconds'].length; i++){
if (source.data['Seconds'][i] > start) {
if (source.data['Seconds'][i] <= end) {
new_data = addRowToAccumulator(new_data, source.data, i);
}
}
}
console.log(new_data)
filtered_source = new_data;
filtered_source.change.emit();
""")
#create slider and add on_change event
testSlider = bmo.RangeSlider(width = 525, bar_color = 'red',
start = 0, end = sample_data['Seconds'].max(),
value=(0,1), step = 1 )
testSlider.js_on_change('value', callback)
#create figure and plot points
p = figure(toolbar_location = 'below',
x_axis_label = 'Longitude', y_axis_label = 'Latitude')
p.circle(x = 'long', y = 'lat', source=filtered_source)
#create layout and show
layout = bla.column(p, testSlider)
show(layout)
作为参考,这是我尝试更改滑块时得到的结果错误:
https://i.stack.imgur.com/OTBEm.png
有人知道我当前的代码有什么问题吗?也感谢有关我的代码的任何反馈。提前谢谢你。
您需要将 new_data
分配给 filtered_source
的 .data
字段。
将行 filtered_source = new_data;
更改为 filtered_source.data = new_data;
时,您的示例对我有用。
我最近开始了一个新项目,需要我在地图上绘制纬度和经度数据。到目前为止,我已经设法绘制出所有内容,但我一直无法为我用来控制绘制哪些数据的范围滑块创建回调函数。
我当前的代码使用 Amstrad2Python 的响应 here 作为其基础。 运行 Amstrad2Python 提供的代码没有给我任何错误。但是,当我尝试 运行 代码时,当我检查 html 图中的控制台输出时,它给我错误“无法读取未定义的 属性 'emit'”。
这是与我使用的实际代码相似的示例代码,它会产生完全相同的错误:
import bokeh.events as bev
import bokeh.layouts as bla
import bokeh.models as bmo
import numpy as np
import pandas as pd
from bokeh.plotting import figure, output_file, show
sample_data = pd.DataFrame(
data=np.array(
[
[1, 12, 21, 15000],
[2, 25, 90, 15500],
[3, 37, 47, 15500],
[4, 41, 56, 15000],
[5, 50, 21, 14500]
]
),
columns=['Seconds', 'lat', 'long', 'alt']
)
#create 2 sources, 1 for editting, 1 for referencing
source = bmo.ColumnDataSource(sample_data) #const data
filtered_source = bmo.ColumnDataSource(sample_data) #alterable data
#create callback function
callback = bmo.CustomJS(args=dict(source=source, filtered_source = filtered_source),
code="""
var data = source.data;
var start = cb_obj.value[0];
var end = cb_obj.value[1];
function generateNewDataObject(oldDataObject){
var newDataObject = {}
for (var key of Object.keys(oldDataObject)){
newDataObject[key] = [];
}
return newDataObject
}
function addRowToAccumulator(accumulator, dataObject, index) {
for (var key of Object.keys(dataObject)){
accumulator[key][index] = dataObject[key][index];
}
return accumulator;
}
var new_data = generateNewDataObject(data);
for (var i = 0; i < source.data['Seconds'].length; i++){
if (source.data['Seconds'][i] > start) {
if (source.data['Seconds'][i] <= end) {
new_data = addRowToAccumulator(new_data, source.data, i);
}
}
}
console.log(new_data)
filtered_source = new_data;
filtered_source.change.emit();
""")
#create slider and add on_change event
testSlider = bmo.RangeSlider(width = 525, bar_color = 'red',
start = 0, end = sample_data['Seconds'].max(),
value=(0,1), step = 1 )
testSlider.js_on_change('value', callback)
#create figure and plot points
p = figure(toolbar_location = 'below',
x_axis_label = 'Longitude', y_axis_label = 'Latitude')
p.circle(x = 'long', y = 'lat', source=filtered_source)
#create layout and show
layout = bla.column(p, testSlider)
show(layout)
作为参考,这是我尝试更改滑块时得到的结果错误:
https://i.stack.imgur.com/OTBEm.png
有人知道我当前的代码有什么问题吗?也感谢有关我的代码的任何反馈。提前谢谢你。
您需要将 new_data
分配给 filtered_source
的 .data
字段。
将行 filtered_source = new_data;
更改为 filtered_source.data = new_data;
时,您的示例对我有用。