from bokeh.plotting import show, figure
from random import random
from bokeh.models import ColumnDataSource, CustomJS, CheckboxButtonGroup, Legend
from bokeh.layouts import column
import numpy as np
import pandas as pd
x = np.arange(10)
a = np.random.rand(10, ) * 20
b = np.random.rand(10, ) * 40
c = np.random.rand(10, ) * 60
df = pd.DataFrame(data={'x': x, 'a': a, 'b': b, 'c': c, 'combined': [0]*10})
source = ColumnDataSource(df)
button_labels = ['a', 'b', 'c']
p = figure(plot_width=1000, plot_height=500, y_range=(0, max(c)*2))
a_line = p.line('x', 'a', source=source, color='red')
b_line = p.line('x', 'b', source=source, color='blue')
c_line = p.line('x', 'c', source=source, color='orange')
combined_line = p.line('x', 'combined', source=source, color='green', line_dash='dashed')
legend = Legend(items=[
('a', [a_line]),
('b', [b_line]),
('c', [c_line]),
('combined (none)', [combined_line]),
], location="center")
p.add_layout(legend, 'right')
callback = CustomJS(args=dict(source=source, legend_item=legend.items[3]), code="""
const labels = cb_obj.labels;
const active = cb_obj.active;
const data = source.data;
const sourceLen = data.combined.length;
const combined = Array(sourceLen).fill(undefined);
var combined_label = ''
if (active.length > 0) {
const selectedColumns = labels.filter((val, ind) => active.includes(ind));
for(let i = 0; i < sourceLen; i++) {
let sum = 0;
for(var col of selectedColumns){
sum += data[col][i];
}
combined[i] = sum;
}
// get index positions of active buttons; use that to retrieve labels to build "combined" label string
for (let j=0; j < active.length; j++) {
combined_label += labels[active[j]]+'+';
}
combined_label = '('+combined_label.substring(0, combined_label.length - 1)+')';
}
else { // if there are no active buttons, label as 'none'
combined_label = '(none)';
}
legend_item.label.value = 'combined '+combined_label;
data.combined=combined;
source.change.emit();
""")
checkbox_group = CheckboxButtonGroup(labels=button_labels, active=[], callback=callback, width=400)
final_col = column(p, checkbox_group)
show(final_col)