9

The official documentation of bokeh 0.12.1 in the link give the below code for creating a dropdown.

http://docs.bokeh.org/en/latest/docs/user_guide/interaction/widgets.html#userguide-interaction-widgets

But it doesn't clearly mention how to capture the value of the dropdown widget when someone click and selects a value from the dropdown.

from bokeh.io import output_file, show
from bokeh.layouts import widgetbox
from bokeh.models.widgets import Dropdown

output_file("dropdown.html")

menu = [("Item 1", "item_1"), ("Item 2", "item_2"), None, ("Item 3", "item_3")]
dropdown = Dropdown(label="Dropdown button", button_type="warning", menu=menu)

show(widgetbox(dropdown))

Question

Is see that there are 2 methods called on_click() & on_change() but from the documentation couldn't figure out how to capture the value. How can we assign the selected value to a new variable?

EDIT

Based on input from @Ascurion i have updated my code as shown below. But when i select a value in dropdown nothing is printed in ipython console in Spyder. Please advise.

    from bokeh.io import output_file, show
    from bokeh.layouts import widgetbox
    from bokeh.models.widgets import Dropdown

    output_file("dropdown.html")


    menu = [("Item 1", "item_1"), ("Item 2", "item_2"), None, ("Item 3", "item_3")]
    dropdown = Dropdown(label="Dropdown button", button_type="warning", menu=menu)

    def function_to_call(attr, old, new):
        print dropdown.value

    dropdown.on_change('value', function_to_call)
    dropdown.on_click(function_to_call)
    show(widgetbox(dropdown))
bigreddot
  • 33,642
  • 5
  • 69
  • 122
GeorgeOfTheRF
  • 8,244
  • 23
  • 57
  • 80

2 Answers2

14

In Bokeh 2.0.0, Dropdown.value was removed. The correct way to get what item has been clicked is:

from bokeh.models import Dropdown

d = Dropdown(label='Click me', menu=['a', 'b', 'c'])


def handler(event):
    print(event.item)


d.on_click(handler)
Eugene Pakhomov
  • 9,309
  • 3
  • 27
  • 53
  • How can we get the value of a dropdown if the dropdown is not being clicked on in Bokeh 2.x.x? In my application, I have multiple dropdowns and I need the "state" of those dropdowns to filter data. – kateryna May 02 '20 at 13:33
  • 1
    Dropdowns are just glorified lists of buttons. They don't have "state". Maybe you're talking about the `Select` widget? – Eugene Pakhomov May 02 '20 at 17:09
  • No, I do refer to the class Dropdown(**kwargs). In Bokeh 1.4.0 it had the attribute value, which was perpetuating the state of the Dropdown button. – kateryna May 04 '20 at 10:30
  • Yes, and it was an API oversight because semantically a button cannot have a value. You can handle its `click` event, that's how it's supposed to work. If you need a selection functionality, you will have to use `Select` or create some custom widget. – Eugene Pakhomov May 04 '20 at 10:53
  • Is a dropdown really a button? To me a dropdown naturally has a state/value. But I am sure you had your motives behind the decision. – kateryna May 04 '20 at 22:03
8

EDIT This answer does not apply for Bokeh Versions 2.X.X anymore. See comment and the other answer below.

If you set on_change e.g. as follows:

dropdown.on_change('value', function_to_call)

one can access the value of the selected item in function_to_call as follows:

def function_to_call(attr, old, new):
    print dropdown.value

For this to work dropdown has to be defined before function_to_call.

The documentation on how to access values set in widgets with on_click and on_change (bokeh version 12.1) can be found here at the top of the page:

http://docs.bokeh.org/en/latest/docs/user_guide/interaction/widgets.html

EDIT

To get interactive feedback you have to run bokeh in server mode, so that the python code can be evaluated when you interact with a widget. I changed your example slightly to allow to be run with the

bokeh serve --show file_name.py

command. The code below then prints out the selected item in the terminal.

from bokeh.io import output_file, show
from bokeh.layouts import widgetbox
from bokeh.models.widgets import Dropdown
from bokeh.plotting import curdoc

menu = [("Quaterly", "time_windows"), ("Half Yearly", "time_windows"), None, ("Yearly", "time_windows")]
dropdown = Dropdown(label="Time Period", button_type="warning", menu=menu)

def function_to_call(attr, old, new):
    print dropdown.value

dropdown.on_change('value', function_to_call)

curdoc().add_root(dropdown)

See here for more information:

http://docs.bokeh.org/en/latest/docs/user_guide/server.html

Ascurion
  • 503
  • 3
  • 13
  • Thanks. I am getting the below error. dropdown.on_change('value', function_to_call(attr, old, new)) NameError: name 'attr' is not defined – GeorgeOfTheRF Aug 23 '16 at 11:59
  • What values for attr, old, new should be passed when function_to_call() is called? Please explain the meaning of these attributes. – GeorgeOfTheRF Aug 23 '16 at 12:00
  • I should just add the codes you mentioned after the codes i mentioned in the question right? – GeorgeOfTheRF Aug 23 '16 at 12:02
  • 1
    Hi sorry my bad you have to give function to call with out arguments and paranthesis to on_change... but the function to call needs the three variables (attr, old, new). I corrected my answer accordingly – Ascurion Aug 23 '16 at 12:32
  • 3
    To add more context: `attr` is the name of the attribute that changed, `old` is the old value (before it was changed) and `new` is the new value. But as you show, if the widget is available as a global it's often just as easy to read the current value off the widget itself. – bigreddot Aug 23 '16 at 13:19
  • I updated code but the value selected in dropdown is not printed by function_to_call(). Please check the EDIT i made to the original post. – GeorgeOfTheRF Aug 23 '16 at 13:55
  • Thanks! I am able to make it work with minor changes! – GeorgeOfTheRF Aug 23 '16 at 16:28
  • Can you please explain this line "curdoc().add_root(dropdown)" ? – GeorgeOfTheRF Aug 23 '16 at 16:33
  • What are the minor changes. For me it works as is when run with the command given in the first line. – Ascurion Aug 24 '16 at 08:10
  • 2
    curdoc() is a function that returns the current Document of the page. A Document is in principle the python representation of the html/css/javascript page created by Bokeh that is than shown in the browser. The add_root(dropdown) adds the dropdown widget to this page. There are possibilities to style the page with layout elements such as rows and columns etc. When run with the `bokeh serve` command the server takes care to serve that document. I have to say that I do not understand the detailed implementation please check also here http://bokeh.pydata.org/en/latest/docs/user_guide/server.html – Ascurion Aug 24 '16 at 08:14
  • Thanks a lot. Can you please help with this one also? http://stackoverflow.com/questions/39119140/how-to-plot-bar-graph-interactively-based-on-value-of-dropdown-widget-in-bokeh-p – GeorgeOfTheRF Aug 24 '16 at 09:49
  • 2
    This is out of date as of Bokeh 2.X. Use `dropdown.on_click(cb)` with `cb(event)`, access element with `event.item` – Will Apr 09 '20 at 10:05
  • thanks for the note, I have edited the answer to point to your comment. – Ascurion Apr 11 '20 at 06:26