I want to make interactive bokeh line charts. I use CheckboxGroup widget to update the charts. However, the charts won't update.
d={'created':['02/01/2019 00:00:00','03/01/2019 00:00:00','04/01/2019 00:00:00','05/01/2019 00:00:00','06/01/2019 00:00:00','07/01/2019 00:00:00'],
'aaa': [5, 4, 10, 7, 5, 5],
'bbb':[0,10,2,9,8,4],
'ccc':[10,12,14,14,5,7]}
df=pd.DataFrame.from_dict(d)
df['created']=pd.to_datetime(df['created'])
df.set_index('created', inplace=True)
plot=figure(plot_width=700,
plot_height=500,
x_axis_type='datetime',
title='lines')
src=ColumnDataSource(df)
products=sorted(list(src.data.keys())[1:])
product_selection=CheckboxGroup(labels=products, active =[0,1])
def make_dataset(initial_dataframe, columns_to_keep):
df=initial_dataframe[columns_to_keep].copy()
src=ColumnDataSource(df)
return src
for i in product_selection.active:
plot.line(x='created', y=product_selection.labels[i], source=src)
def update(attr, old, new):
prods=[product_selection.labels[i] for i in product_selection.active]
src=make_dataset(df,prods)
product_selection.on_change('active', update)
layout=row(plot,product_selection)
curdoc().add_root(layout)
Please help me to correct my code.
If you want to show / hide the lines at checkbox selection then you could do it this way by using visibility
attribute of a glyph (run the code with bokeh serve --show app.py
):
from bokeh.models import CheckboxGroup, ColumnDataSource, Row
from bokeh.plotting import figure, curdoc
import pandas as pd
d={'created':['02/01/2019 00:00:00','03/01/2019 00:00:00','04/01/2019 00:00:00','05/01/2019 00:00:00','06/01/2019 00:00:00','07/01/2019 00:00:00'],
'aaa': [5, 4, 10, 7, 5, 5],
'bbb': [0, 10, 2, 9, 8, 4],
'ccc': [10, 12, 14, 14, 5, 7]}
df=pd.DataFrame.from_dict(d)
df['created']=pd.to_datetime(df['created'])
df.set_index('created', inplace=True)
plot=figure(plot_width=700,
plot_height=500,
x_axis_type='datetime',
title='lines')
src=ColumnDataSource(df)
products=sorted(list(src.data.keys())[1:])
product_selection=CheckboxGroup(labels=products, active =[0,1])
lines = []
for i, column in enumerate(df.columns.tolist()):
line = plot.line(x='created', y=column, source=src)
line.visible = i in product_selection.active
lines.append(line)
def update(attr, old, new):
for i, renderer in enumerate(lines):
if i in product_selection.active:
renderer.visible = True
else:
renderer.visible = False
product_selection.on_change('active', update)
curdoc().add_root(Row(plot,product_selection))