Search code examples
python-3.xbokehbokehjs

CheckBoxGroup is not updating in Python/Bokeh


I am trying to create a dashboard of data for our university, and have run into a problem with how it is presenting. I am using Bokeh and Python to create somewhat interactive graphs. My checkbox group is not updating when I click a box to select the college for the major. I have tried changing several items, but cannot figure out what I am doing wrong.

My code:

# Available college list
available_colleges = list(df['College'].unique())

source_maj = ColumnDataSource(df)
grouped_maj = df.groupby('Major').sum()
source_maj = ColumnDataSource(grouped_maj)
major = source_maj.data['Major'].tolist()

p_maj = figure(x_range=major, width=1100, height=500)
p_maj.xaxis.major_label_orientation = math.pi/4


color_map = factor_cmap(field_name='Major',
                    palette=Magma11, factors=level)

p_maj.vbar(x='Major', top='AY2018_19', source=source_maj, width=0.2, color=color_map)

p_maj.title.text ='Enrollment by Major'
p_maj.xaxis.axis_label = 'Major'
p_maj.yaxis.axis_label = 'Enrolled Students'

hover = HoverTool()
hover.tooltips = [
    ("2019-2020", "@AY2019_20"),
    ("2018-2019", "@AY2018_19"),
    ("2017-2018", "@AY2017_18")]

hover.mode = 'vline'


callback = CustomJS(args=dict(source=source_maj), code="""
    const labels = cb_obj.labels;
    const active = cb_obj.active;
    const data = source_maj.data;
    const sourceLen = data.combined.length;
    const combined = Array(sourceLen).fill(undefined);
    if (active.length > 0) {
        const selectedColumns = labels.filter((val, ind) => active.includes(ind));
        for(let i = 0; i < sourceLen; i++) {
            let sum = 0;
            for(col of selectedColumns){
                sum += Major[col][i];
            }
            combined[i] = sum;
        }
    }
    Major.combined=combined;
    source_maj.change.emit();
""")

colleges_selection = CheckboxGroup(labels=available_colleges, active = [0], callback=callback)

controls = WidgetBox(colleges_selection)
p_maj = row(controls, p_maj)

Data is formated in a csv sheet that is being read

Sample Data

What it looks like, but nothing updates What current graph(s) look like

Any help is greatly appreciated.


Solution

  • You'll probably want to watch the output the browser sends to the javascript console; it'll tell you what's going wrong here.

    A couple places to start: your arguments to the CustomJS object bring in the python object 'source_maj' and rename it as 'source', but then in your JS code you refer to it as 'source_maj'. Also, your JS code makes reference to 'Major', but this isn't an object that the JS knows about (i.e. it wasn't brought in with the args).