Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CheckboxGroup active list not updating #4

Open
fabhlc opened this issue May 25, 2018 · 6 comments
Open

CheckboxGroup active list not updating #4

fabhlc opened this issue May 25, 2018 · 6 comments

Comments

@fabhlc
Copy link

fabhlc commented May 25, 2018

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!

@WillKoehrsen
Copy link
Owner

WillKoehrsen commented May 26, 2018

The code here seems to work for generating the histogram by itself. The code you show I think is from the complete application, while the code linked to is for the histogram by itself. Are you trying to run the entire application, or just the histogram?

(To run use bokeh serve --show histogram.py from the command line in the directory with histogram.py)

The complete update function is

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,
                                                        range_start = range_select.value[0],
                                                        range_end = range_select.value[1],
                                                        bin_width = binwidth_select.value)
	
		src.data.update(new_src.data)

so it looks like you have the right update function. I would try going to the code I linked above and trying to run that by itself. The application code has to be formatted slightly differently than the stand-alone plot which might explain the issue.

@fabhlc
Copy link
Author

fabhlc commented May 26, 2018

I'm trying to run the entire application as per your second tutorial (minus the range and bin width sliders widgets) in order to get the CheckboxGroup widget to work.

The initial histogram gets created just fine - it's the updating action that doesn't work. (e.g. clicking on checkboxes don't result in any action).

Thanks

p.e. I use Jupyter Notebook so I've been creating the plots inline.

@fabhlc
Copy link
Author

fabhlc commented May 27, 2018

Update: this works on Bokeh servers, which I wasn't using before. Cheers!

@WillKoehrsen
Copy link
Owner

WillKoehrsen commented May 27, 2018

That's good to hear!

Sorry, I was trying to say that it should work in a Bokeh server before, but I don't think I was very clear. If you're trying to run it in a Jupyter Notebook in the future, there's a slightly different set of steps to get the interactivity.

@jazib-jamil
Copy link

Hi, I read all the comments. I'm trying to run it on Jupyter/Spyder. I want to know the difference needed to make code work.
Thanks

@markgithub111
Copy link

markgithub111 commented Sep 14, 2020

I had a similar problem to the one fabhlc did. The updating problem happened because of the deprecation of "legend." I struggled to find the solution but eventually figured out that you had to use legend_field, not legend_group. The solution is explained here: https://docs.bokeh.org/en/latest/docs/reference/plotting.html.

My question is different though. I have this running in the Jupyter notebook, but I would like to run the code in a browser, not in the Jupyter notebook (so that I can give the plot to someone else to use). I can't figure out how to do that. I've used the output to html feature on the passively interactive plot (from Part I of the article) and that works fine. But the actively interactive one will not save to an html file. I would be happy to learn how to do this. To be clear, I don't care what format the output is on, I just want people to just click on an icon and get the interactive visualization to work. Like I do in Plotly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants