from vega_datasets import data from scipy import stats from bokeh.plotting import figure from bokeh.models import ColumnDataSource import panel as pn import numpy as np # Tell banel to use Bokeh pn.extension() # Get the data source = data.movies() temp = sorted(source['IMDB_Rating'].dropna().values) # compute an initial number of bins n_int_bins = int(np.ceil(max(temp))+ 1 - np.floor(min(temp))) # define a function that takes the parameters and creates the plot def create_plot(bandwidth=1.0, bins=n_int_bins): plot = figure(width=300, height=300, toolbar_location=None) # Compute the histogram with the specified number of bins hist, edges = np.histogram(temp, bins=bins) # normalize and plot it hist = hist / hist.sum() quad = plot.quad(top=hist, bottom=0, left=edges[:-1], right=edges[1:], fill_color="grey", line_color="white", alpha=0.5) # Compute the density with the specified bandwidth kernel = stats.gaussian_kde(temp, bw_method=bandwidth) x = np.linspace(min(temp), max(temp), 100) y = kernel(x) col_source = ColumnDataSource(data=dict(x=x, y=y)) line = plot.line('x', 'y', source=col_source, alpha=1.0, width=2) return plot # Create widgets for the bandwidth and number of bins bw_widget = pn.widgets.FloatSlider(name="Bandwidth", value=1.0, start=0.03, end=2.0, step=0.02) bins_widget = pn.widgets.IntSlider(name="Number of Bins", value=n_int_bins, start=1, end=n_int_bins*10) # bind the sliders to the plotting function bound_plot = pn.bind(create_plot, bandwidth=bw_widget, bins=bins_widget) # Combine everything together first_app = pn.Column(bw_widget, bins_widget, bound_plot) first_app.servable()