flamenco
flamenco

Reputation: 2840

How to mirror widgets in Bokeh?

Imagine that you have two pairs of Bokeh widgets:

widget1 = widgetbox(input1=TextInput(...), multiselect1=MultiSelect(...))
widget2 = widgetbox(input2=TextInput(...), multiselect2=MultiSelect(...))

Both, multiselect1 and multiselect2, are initially populated with the same options, let's say ['apples', 'oranges', 'grapes'].
Both inputs, input1 and input2 are used to collect input from user and filter(update) the object in multiselect widgets according to that input.
For example, if a user enters apples in input1, multiselect1 will get updated and show only apples, discarding the others.

The question is how to make both widgets work in tandem or have them mirror each other if you will? So, both widgets will show the same objects, regardless if a user enters text in input1 or input2.

I have tried to create widget2 as a copy of widget1, thinking that both will reference the same object, so, when the object gets updated, either reference, widget1 and widget2, will display the updated object but it doesn't work.
I'm speculating that when Bokeh renders the Python code in JavaScript it assigns a unique ID to each object, and from here they become independent. If you have an idea, please, let me hear it!
Cheers!

Upvotes: 0

Views: 76

Answers (1)

bigreddot
bigreddot

Reputation: 34568

The stocks example is a good one to refer to:

https://github.com/bokeh/bokeh/blob/master/examples/app/stocks/main.py

It's going in the opposite direction, i.e. it's removing whatever is in one ticker from the other, but the principe is the same, update the options property of the widget with whatever you need. Here is the relevant portion of the stocks example:

DEFAULT_TICKERS = ['AAPL', 'GOOG', 'INTC', 'BRCM', 'YHOO']

def nix(val, lst):
    return [x for x in lst if x != val]

def ticker1_change(attrname, old, new):
    ticker2.options = nix(new, DEFAULT_TICKERS)
    update()

def ticker2_change(attrname, old, new):
    ticker1.options = nix(new, DEFAULT_TICKERS)
    update()

So if a user selects AAPL from the first select then AAPL will be removed from the second. In your case, you would have a callback on the inputs that set the select options appropriately to your use case.

If this is outside the context of a Bokeh server app, then you could also accomplish the same thing with CustomJS callbacks instead of Python callbacks.

Upvotes: 1

Related Questions