1

I would like to choose a subsection from a selection.

I have a dataframe like the following.

df = pd.DataFrame()
df['People'] = ['Eva', 'John', 'Paul','Mr a', 'Miss b', 'Mrs c' ]
df['Type']   = ['Students', 'Students', 'Students', 'Teachers', 'Teachers', 'Teachers']

Let say we have Student and Teachers.

select  =  Select(title="People",  options=['Student', 'Teachers' ])

Then we have three students: Eva, John, Paul and three teachers Mr a, Miss b and Mrs c

How can we create a second selection select2 that choose Eva, John, Paul if we select teachers and Mr a, Miss b and Mrs c if we select Teachers.

select2  =  Select(title="Selected",  options=[ (`Eva`, `John`, `Paul`), (Mr a`, `Miss b`, `Mrs c`)] ])

This what I have in mind

select_data = Select(title="Type",  options=['None', 'Students', 'Teachers' ], value = '')
dynamic_select = Select(title = 'People', value = ''  , 
                        options = ['None','Eva', 'John', 'Paul','Mr a', 'Miss b', 'Mrs c' ] )
controls = widgetbox(select_data, dynamic_select)
layout = column(row(controls))

def update_layout(attr, old, new):
        if select_data.value == 'Students':
            dynamic_select = Select(title = 'People', value = '', options = ['Eva', 'John', 'Paul'])
        if select_data.value == 'Teachers':
            dynamic_select = Select(title = 'People', value = '', options = ['Mr a', 'Miss b', 'Mrs c'])
        if select_data.value == 'None':
            dynamic_select = Select(title = 'People', value = '', options = ['None'])     


select_data.on_change('value', update_layout)
dynamic_select.on_change('value', update_layout)
curdoc().add_root(layout)

1 Answer 1

3

With this code you can dynamically add / remove a second Select widget. Is this what you wanted?

from bokeh.plotting import curdoc, show
from bokeh.models import Select, Column, Div
from datetime import datetime, timedelta
import numpy as np

students = ['Eva', 'John', 'Paul']
teachers = ['Mr a', 'Miss b', 'Mrs c']
select_data = Select(title="People",  options=['', 'Students', 'Teachers' ], value = '')
layout = Column(select_data)

def update_layout(attr, old, new):
    if new:
        if len(layout.children) > 1 and layout.children[len(layout.children) - 1].title != new:
            layout.children.remove(layout.children[len(layout.children) - 1])

        options = students if new == 'Students' else teachers
        dynamic_select = Select(title = '{}'.format(new), value = '', options = options)
        layout.children.append(dynamic_select)

select_data.on_change('value', update_layout)
curdoc().add_root(layout)

enter image description here

Sign up to request clarification or add additional context in comments.

8 Comments

thanks for the answer. I added a couple of comments to that. Because in my real case I have a dataframe with multiple cases. I just wrote that example that was simple. I modified the question with a dataframe. I am wondering how can I do that in this case.
is it possible to do a similar menu without making widgets appearing and disappearing?
Do you mean to add permanently a new widget each time when you make a selection in the first one? Then just remove the line containing layout.children.remove and the proceeding if statement.
I would like to have a fixed widget that changes only the options.
Then you just assign a new list to the options property of a Select widget: select.options = ['cats','dogs']
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.