在 Bokeh JS 回调中将 .filter() 应用于 ColumnDataSource
Applying .filter() to ColumnDataSource in Bokeh JS Callback
问题:我无法将过滤器函数应用于列数据源,即使在应用它之后也会提供我的整个完整数组。我对 JS 的不熟悉让事情变得更糟。
所以我一直在尝试从这里重现结果:
但使用我自己的数据源。
这里是JS回调的代码:
# Create slider callback
SliderCallback = CustomJS(args = dict(sliceCDS=sliceCDS, fullCDS=fullCDS, indexCDS=indexCDS), code = """
const new_value = cb_obj.value;
// Take the 'Slice' column from the full data
const slice_col = fullCDS.data['Slice'];
// Select only the values equal to the new slice number
const mask = slice_col.map((item) => item==new_value);
sliceCDS.data['x'] = fullCDS.data['x'].filter(item => mask);
sliceCDS.data['y'] = fullCDS.data['y'].filter(item => mask);
sliceCDS.data['label'] = fullCDS.data['label'].filter(item => mask);
//console.log('Here is the data');
console.log(sliceCDS.data['x']);
console.log(sliceCDS.data['y']);
console.log(sliceCDS.data['label']);
// Update the sliceCDS
sliceCDS.change.emit();
""")
# Set up slider
slider = bokeh.models.Slider(title="Slice view number: ",start=0, end=49,value=0,step=1)
slider.js_on_change('value', SliderCallback)
这里是sliceCDS(Input to JS callback):
{'x': 0 -0.001215
0 0.001454
0 -0.000191
0 -0.000377
0 -0.000008
...
0 0.001993
0 0.002045
0 0.002220
0 -0.003160
0 -0.000088
Name: x, Length: 1797, dtype: float64, 'y': 0 0.000745
0 0.000171
0 -0.000004
0 0.000268
0 0.000535
...
0 -0.000417
0 0.002719
0 -0.000269
0 0.000766
0 0.000250
Name: y, Length: 1797, dtype: float64, 'label': 0 0
0 0
0 0
0 0
0 0
..
0 9
0 9
0 9
0 9
0 9
Name: label, Length: 1797, dtype: int64, 'Slice': 0 0
0 0
0 0
0 0
0 0
..
0 0
0 0
0 0
0 0
0 0
Name: Slice, Length: 1797, dtype: int64}
这里是fullCDS(Input to JS callback):
{'x': 0 -0.001215
0 0.001454
0 -0.000191
0 -0.000377
0 -0.000008
...
49 -12.208837
49 -11.620906
49 -16.709465
49 -13.481855
49 -12.067336
Name: x, Length: 89850, dtype: float64, 'y': 0 0.000745
0 0.000171
0 -0.000004
0 0.000268
0 0.000535
...
49 28.264780
49 27.768742
49 27.019316
49 27.537040
49 24.889742
Name: y, Length: 89850, dtype: float64, 'label': 0 0
0 0
0 0
0 0
0 0
..
49 9
49 9
49 9
49 9
49 9
Name: label, Length: 89850, dtype: int64, 'Slice': 0 0
0 0
0 0
0 0
0 0
..
49 49
49 49
49 49
49 49
49 49
Name: Slice, Length: 89850, dtype: int64}
使用上面的代码我无法更新我的 sliceCDS。它仍然包含所有 89850 行,而在应用 .filter() 后它应该只包含 1797 行。
编辑:根据建议,我还在函数中尝试了以下内容:
sliceCDS.data['x'] = fullCDS.data['x'].filter((item,idx) => mask[idx]);
它给了我以下错误:
VM499:17 Uncaught TypeError: Cannot read property 'filter' of undefined
也试过这个:
sliceCDS.data['x'] = fullCDS.data['x'].filter((item,0) => mask[0]);
这给了我这个错误:
VM505:31 Uncaught SyntaxError: Invalid destructuring assignment target
但是如果我尝试上面给出的 link 中的方法,我的列数据源中的列名称为 Line1 表示 x,Line2 表示 y,Line3 表示标签:
// Update the data for sliceCDS with a slice of data from fullCDS
for(i=1; i<3; i++){
sliceCDS.data['Line' + i.toString()] = fullCDS.data['Line' + i.toString()].filter((item,i) => mask[i]);
}
上面的代码工作得很好。
但是为什么一开始提到的案例代码不起作用?我确定我使用 .filter() 的方式有问题。
你那里有这个表达式。
fullCDS.data['x'].filter(item => mask);
item => mask
总是returnsmask
,不管item
是什么。在 JavaScript 中,无论内容如何,数组始终为 truth-y。
过滤函数的第二个参数是项目的索引。尝试改用 (item, idx) => mask[idx]
lambda。
问题:我无法将过滤器函数应用于列数据源,即使在应用它之后也会提供我的整个完整数组。我对 JS 的不熟悉让事情变得更糟。
所以我一直在尝试从这里重现结果:
但使用我自己的数据源。
这里是JS回调的代码:
# Create slider callback
SliderCallback = CustomJS(args = dict(sliceCDS=sliceCDS, fullCDS=fullCDS, indexCDS=indexCDS), code = """
const new_value = cb_obj.value;
// Take the 'Slice' column from the full data
const slice_col = fullCDS.data['Slice'];
// Select only the values equal to the new slice number
const mask = slice_col.map((item) => item==new_value);
sliceCDS.data['x'] = fullCDS.data['x'].filter(item => mask);
sliceCDS.data['y'] = fullCDS.data['y'].filter(item => mask);
sliceCDS.data['label'] = fullCDS.data['label'].filter(item => mask);
//console.log('Here is the data');
console.log(sliceCDS.data['x']);
console.log(sliceCDS.data['y']);
console.log(sliceCDS.data['label']);
// Update the sliceCDS
sliceCDS.change.emit();
""")
# Set up slider
slider = bokeh.models.Slider(title="Slice view number: ",start=0, end=49,value=0,step=1)
slider.js_on_change('value', SliderCallback)
这里是sliceCDS(Input to JS callback):
{'x': 0 -0.001215
0 0.001454
0 -0.000191
0 -0.000377
0 -0.000008
...
0 0.001993
0 0.002045
0 0.002220
0 -0.003160
0 -0.000088
Name: x, Length: 1797, dtype: float64, 'y': 0 0.000745
0 0.000171
0 -0.000004
0 0.000268
0 0.000535
...
0 -0.000417
0 0.002719
0 -0.000269
0 0.000766
0 0.000250
Name: y, Length: 1797, dtype: float64, 'label': 0 0
0 0
0 0
0 0
0 0
..
0 9
0 9
0 9
0 9
0 9
Name: label, Length: 1797, dtype: int64, 'Slice': 0 0
0 0
0 0
0 0
0 0
..
0 0
0 0
0 0
0 0
0 0
Name: Slice, Length: 1797, dtype: int64}
这里是fullCDS(Input to JS callback):
{'x': 0 -0.001215
0 0.001454
0 -0.000191
0 -0.000377
0 -0.000008
...
49 -12.208837
49 -11.620906
49 -16.709465
49 -13.481855
49 -12.067336
Name: x, Length: 89850, dtype: float64, 'y': 0 0.000745
0 0.000171
0 -0.000004
0 0.000268
0 0.000535
...
49 28.264780
49 27.768742
49 27.019316
49 27.537040
49 24.889742
Name: y, Length: 89850, dtype: float64, 'label': 0 0
0 0
0 0
0 0
0 0
..
49 9
49 9
49 9
49 9
49 9
Name: label, Length: 89850, dtype: int64, 'Slice': 0 0
0 0
0 0
0 0
0 0
..
49 49
49 49
49 49
49 49
49 49
Name: Slice, Length: 89850, dtype: int64}
使用上面的代码我无法更新我的 sliceCDS。它仍然包含所有 89850 行,而在应用 .filter() 后它应该只包含 1797 行。 编辑:根据建议,我还在函数中尝试了以下内容:
sliceCDS.data['x'] = fullCDS.data['x'].filter((item,idx) => mask[idx]);
它给了我以下错误:
VM499:17 Uncaught TypeError: Cannot read property 'filter' of undefined
也试过这个:
sliceCDS.data['x'] = fullCDS.data['x'].filter((item,0) => mask[0]);
这给了我这个错误:
VM505:31 Uncaught SyntaxError: Invalid destructuring assignment target
但是如果我尝试上面给出的 link 中的方法,我的列数据源中的列名称为 Line1 表示 x,Line2 表示 y,Line3 表示标签:
// Update the data for sliceCDS with a slice of data from fullCDS
for(i=1; i<3; i++){
sliceCDS.data['Line' + i.toString()] = fullCDS.data['Line' + i.toString()].filter((item,i) => mask[i]);
}
上面的代码工作得很好。
但是为什么一开始提到的案例代码不起作用?我确定我使用 .filter() 的方式有问题。
你那里有这个表达式。
fullCDS.data['x'].filter(item => mask);
item => mask
总是returnsmask
,不管item
是什么。在 JavaScript 中,无论内容如何,数组始终为 truth-y。
过滤函数的第二个参数是项目的索引。尝试改用 (item, idx) => mask[idx]
lambda。