Search code examples
widgetsliderbokeh

Bokeh: Slider is not updating results on Hbar plot


I wrote the following code for using a slider to filter and update values on a Hbar plot in Bokeh. The plot (as shown in the picture) outputs correctly, but when I move the slider nothing happens. I'd greatly appreciate any feedback.

import pandas as pd
from bokeh.core.properties import value
from IPython.display import display, HTML
from bokeh.plotting import figure, show
from bokeh.layouts import row, column, gridplot
from bokeh.io import output_notebook, save, curdoc
from bokeh.models import ColumnDataSource, HoverTool, DatetimeTickFormatter, FactorRange, DataTable, TableColumn, DateFormatter
from bokeh.models.widgets import Panel, Tabs, Slider
import matplotlib.pyplot as plt

xls=pd.ExcelFile(path)
test_data=pd.read_excel(xls, 'test_data')

display(test_data)

AREA    counts
A   500
B   100
C   70
D   50
E   40
F   20
G   10
H   2

def myplot(doc):

    source = ColumnDataSource(pd.DataFrame(data=test_data))
    area_list=source.data['AREA'].tolist()[::-1]

# Creating the Bar Chart

    p = figure(y_range=area_list ,plot_height=500, plot_width=500, title="Total counts per area",
           x_axis_label='counts', y_axis_label='AREA')
           

    p.hbar(y='AREA', right='counts',  height=1, 
            line_color="black", fill_color='red',line_width=1, 
            source=source)

    def update_plot(attr, old, new):

        Number_of_counts = slider.value
        new_data = test_data.loc[test_data['counts'] >=Number_of_counts]
        source = ColumnDataSource(data=new_data)


# Make a slider object: slider
    slider = Slider(start=1, end=100, step=1, value=1, title='counts')

# Attach the callback to the 'value' property of slider
    slider.on_change('value', update_plot)
 
    doc.add_root(column(slider, p))


show(myplot)

enter image description here


Solution

  • You're replacing the value of the source variable, but the old source is still there, being used by all the created models.

    Instead of recreating the source, try to reassign the data attribute of the old source:

    # source = ColumnDataSource(data=new_data)
    source.data = ColumnDataSource.from_df(new_data)