Hi,
I'm trying to replicate the second in your series of tutorials but am having trouble with the CheckboxGroup part. While the initial carriers load and appear, there seems to be a disconnect that's preventing the CheckboxGroup active list from updating data displayed in the histogram. So when I check or uncheck a box, it won't be reflected in the histogram.
I've removed the binwidth and range sliders to cut down on the problem. Otherwise the code below is essentially as the original in your github.
def` histogram_bokeh(flights):
def make_dataset(carrier_list, range_start = -60, range_end = 120, bin_width=5):
#check to make sure start is less than end:
assert range_start < range_end, "Start must be less than end!"
by_carrier = pd.DataFrame(columns=['proportion', 'left', 'right',
'f_proportion', 'f_interval',
'name', 'color'])
range_extent = range_end - range_start
for i, carrier_name in enumerate(carrier_list):
#subset to the carrier
subset = flights[flights['name'] == carrier_name]
# Create a histogram
arr_hist, edges = np.histogram(subset['arr_delay'],
bins = int(range_extent / bin_width),
range = [range_start, range_end])
# Divide the counts by the total to get a proportion and create df
arr_df = pd.DataFrame({'proportion': arr_hist / np.sum(arr_hist),
'left': edges[:-1],
'right': edges [1:]})
#Format the proportion
arr_df['f_proportion'] = ['%0.5f' % proportion for proportion in arr_df['proportion']]
#Format the interval
arr_df['f_interval'] = ['%d to %d minutes' % (left, right) for left,
right in zip(arr_df['left'], arr_df['right'])]
#Assign the carrier for labels
arr_df['name'] = carrier_name
#Colour each carrier differently
arr_df['color'] = Category20_16[i]
#Add to the overall dataframe
by_carrier = by_carrier.append(arr_df)
# Overall dataframe
by_carrier = by_carrier.sort_values(['name','left'])
#Convert dataframe to column data source
return ColumnDataSource(by_carrier)
def make_plot(src):
# Blank plot with correct labels
p = figure(plot_width = 700, plot_height = 700,
title = "Histogram of Arrival Delays by Carrier",
x_axis_label = 'Delay (min)', y_axis_label = 'Proportion')
# Quad glyphs to create a histogram
p.quad(source = src, bottom = 0, top = 'proportion', left = 'left', right = 'right',
color = 'color', fill_alpha = 0.7, hover_fill_color = 'color', legend = 'name',
hover_fill_alpha = 1.0, line_color = 'black')
# HoverTool
hover = HoverTool(tooltips=[('Carrier', '@name'),
('Delay', '@f_interval'),
('Proportion', '@f_proportion')])
p.add_tools(hover)
return p
def update(attr, old, new):
carriers_to_plot = [carrier_selection.labels[i] for i in carrier_selection.active]
new_src = make_dataset(carriers_to_plot)
src.data.update(new_src.data)
carrier_selection = CheckboxGroup(labels = available_carriers, active=[0,1,9])
carrier_selection.on_change('active', update)
initial_carriers = [carrier_selection.labels[i] for i in carrier_selection.active]
src = make_dataset(initial_carriers)
p = make_plot(src)
controls = WidgetBox(carrier_selection)
# Create a row layout
layout = row(controls, p)
# make a tab with the layout
tab = Panel(title = "histogram", child = layout)
tabs = Tabs(tabs=[tab]) #add tab2 to list for additional tabs
return tabs
show(histogram_bokeh(flights))
Note that I found I need Panels in the last section to make it work. Otherwise, essentially the same. I suspect there might be something in the update function that's causing it to not work?
I am using bokeh 0.12.16.
Thanks!