The problem: I am not able to apply a filter function to columndatasource, and even after applying it's giving my entire full array. My lack of familiarity with JS is making things worse.
So I've been trying to reproduce the results from here:
But using my own data source.
Here is the code for JS Callback:
# 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)
Here is 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}
Here is 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}
With the above code I am not able to update my sliceCDS. It still contains all 89850 rows, when it should contains only 1797 after applying .filter(). EDIT: on suggestion, I also tried the following in the function:
sliceCDS.data['x'] = fullCDS.data['x'].filter((item,idx) => mask[idx]);
and it gives me following error:
VM499:17 Uncaught TypeError: Cannot read property 'filter' of undefined
and tried with this also:
sliceCDS.data['x'] = fullCDS.data['x'].filter((item,0) => mask[0]);
which gave me this error:
VM505:31 Uncaught SyntaxError: Invalid destructuring assignment target
But if I try the method from the link given above, with names of the columns in my columndatasources as Line1 for x, Line2 for y and Line3 for label:
// 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]);
}
The above code works just fine.
But why is the code for case mentioned in the starting not working? I am sure there's something wrong with the way I am using .filter().
You have this expression in there.
fullCDS.data['x'].filter(item => mask);
The item => mask
always returns the mask
, regardless of what item
is. In JavaScript, an array is always truth-y, no matter the contents.
The second argument to the filter function is the index of the item. Try using the (item, idx) => mask[idx]
lambda instead.