I am trying to display a bar chart and have the contents filtered by a Select object. As simple as it seems, I have not been able to find a working solution after two days of looking. I need to do this with CustomJS, not bokeh server.
Here is the code I am trying, but when I run it nothing is displayed, not even an empty plot.
import pandas as pd
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, CustomJS, CustomJSFilter, CDSView, Select, IndexFilter
from bokeh.io import show, output_notebook
from bokeh.layouts import column
output_notebook()
df = pd.DataFrame({'Subject': ['Math', 'Math', 'Math', 'Science', 'Science', 'Science'],
'Class': ['Algebra', 'Calculus', 'Trigonometry', 'Biology', 'Chemistry', 'Physics'],
'FailRate': [0.05, 0.16, 0.31, 0.12, 0.20, 0.08]})
src = ColumnDataSource(df)
subj_list = sorted(list(set(src.data['Subject'])))
callback = CustomJS(args=dict(src=src), code='''
src.change.emit();
''')
js_filter = CustomJSFilter(code='''
var indices = [];
for (var i = 0; i < src.get_length(); i++){
if (src.data['Subject'][i] == select.value){
indices.push(true);
} else {
indices.push(false);
}
}
return indices;
''')
options = ['Please select...'] + subj_list
select = Select(title='Subject Selection', value=options[0], options=options)
select.js_on_change('value', callback)
view = CDSView(source=src, filters=[js_filter])
class_list = sorted(list(src.data['Class']))
p = figure(x_range=class_list, plot_height=400, plot_width=400)
p.vbar('Class', top='FailRate', width=0.9, source=src, view=view)
show(column(select, p))
As far as I can tell, part of the problem involves this line (or the ‘view’ variable):
p.vbar('Class', top='FailRate', width=0.9, source=src, view=view)
Before I added ‘view=view’ to the above line, I was at least getting a select box and plot displayed, even though the interaction was not working.