Search code examples
pythonbokeh

Cannot update Bokeh chart with CheckboxGroup


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.


Solution

  • 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))
    

    Result: enter image description here