Callbacks with a drop down with multi select

Hi, I am somewhat new to Dash and I was wondering if someone can help out. I am currently trying to build a dashboard and I have been struggling for past 4 hours with how to do callbacks where you can do a dropdown where you can have multiple selection.

I basically want to plot in an overlayed bar graph the data stored in a panda dataframe. Here is what the code looks like.

I pull the data from a local server so ignore this

df = pd.read_html()

app.layout = html.Div([
dcc.Graph(id=‘id-graph’),
dcc.Dropdown(id=‘id-dropdown’,options = [{‘label’:i} for i in df[“Machine”].values],
multi=True, value=)])

##For every value, I will have to find the corresponding info in the table and return it for plot

@app.callback(
dash.dependencies.Output(‘id-graph’, ‘figure’),
[dash.dependencies.Input(‘id-dropdown’, ‘value’)])
def update_graph(values):
# prepare figure_a from value
if values == :
values = df[“Value”].values[0]
for val in values:
df_plot = df[df[‘Value’] == val]

        ## Basically here, I want to get the values that are selected in the dropdown
        ## Add them to a trace where I plot the bars, and return the figure containing them

if name == ‘main’:
app.run_server(debug = True)

Thanks for the help in advance, I did all the user guide and still couldn’t come across something that solved my issue

1 Like

The closest thing I can think of is a dropdown with multi=True. You still have to select one element at a time from the dropdown, but you can select multiple values and they’ll appear in the dropdown field as selected (and with a ‘x’ to delete them if you need to). You can check the section on ‘Multi-Value Dropdown’ here:

https://dash.plot.ly/dash-core-components/dropdown

My multi dropdown look like this:

dcc.Dropdown(
                id='your-dropdown-id',
                options=[{'label': i, 'value': i} for i in variable_name],
                value= variable_name,
                multi=True,
            ),
1 Like

I do have multi = True in the dcc.Dropdown. The issue is, I don’t know how to deal with it in callback. Because once someone selects multiple, how do I display the multiple overlayed graphs? Its that part that I am having a problem with

1 Like

I think you’d have to alter this part to accommodate multiple plots.
i think instead of having a for loop for it, you can pass the “val” as a parameter (e.g. color) and pass one df without the for loop

All right, this answer is provided a bit late, but I find a solution for Dataframes with “isin” :
My example is the following :

dcc.Dropdown(
                  id = "dropdown_geoloc",
                  options= list_region, #The list has around 6/7 cities
                  value=['Zürich', 'Basel'], #Initial values,
                  multi=True)

@app.callback(
    Output(component_id='fig-map',component_property='figure'),
    [Input(component_id='dropdown_geoloc', component_property='value'])

def update_df(town):
	new_df = df1[(df1['region'].isin(town)]
6 Likes

Nicely done! @qdumont
Your approach worked for me

1 Like

Hi,

To extend this scenario - how can we configure dropdown to deal with ‘No selections’ at all. Say if a user chooses to have everything displayed rather than just a subset as specified by the dropdown, how can dcc.Dropdown be configured to deal with [] or ‘Select All’ scenario?

thanks

thank you @qdumont

that worked for me also!

1 Like

Hey @aiyer1,

Sorry for the late reply, unfortunately I do not see any workaround yet. Maybe using

dcc.RadioItems(
    options=[
        {'label': 'All values', 'value': 'All'},
        {'label': 'No Values', 'value': 'No'},
    ],
    id = 'dropdown-all-values',
    value='All'
)  

and use it within the Dropdown callback.

1 Like

What is returned from a multi select drop down? Is it a string? or a list?
Thank you!

Hi @zaz
You can always do print(type(value)) to see what type is returned.

The answer is a list

@adamschroeder Thank you! Yes that’s eventually what I ended up doing. For some reason, I thought I would see it in the documentation and I even though it said it was a list, I am getting an error in one of my functions where I am passing the variable assigned to the list (returned by the multi drop down) when I am trying to use append() in that function… I will continue to investigate that, but it was throwing me off for sure. Thanks again!

Hi @zaz

Are you still getting an error? If so it might be caused by using append() in the callback. It may be similar to the issue in this topic: Updating a variable used in DataTable's style_data_conditional

1 Like

@AnnMarieW Thank you for the reference! Yes it is still happening but I will check out the link you sent!

What I did:
set the dataframe to the full record set at start of callback. Then filter the data frame on the dropdown selections within if bool(dropdown value) clauses.

Note ‘make_map’ is a function to draw the figure as specified elsewhere.

@app.callback(
    Output('map', 'figure'),
    [Input('dropdown-column_name', 'value') ])
def update_graph(column_name_values):
    df = full_dataframe
    if bool(column_name_values): #If nothing is selected, this is falsy so no filtering
        df = df[df['column_name'].isin(column_name_values)]     
    return make_map(df)
1 Like

appreciate this solution @lpearson

Hello please find below an example of a dropdown with multiple selection ( the idea is to nest checklist in dropdown menu):

dbc.DropdownMenu(
                    label="Menu",
                    menu_variant="dark",
                    children=[
                        dbc.Checklist(
                            options=[
                                {"label": "Option 1", "value": 1},
                                {"label": "Option 2", "value": 2},
                                {"label": "Disabled Option", "value": 3, "disabled": True},
                            ],
                            value=[1],
                            id="checklist-input",
                            class_name='p-1'
                        )
                    ],
                )

with this component writing the callback will be an easy task :smiley:

1 Like

I can give you an answer based on my use case:
if loanStatus is None or len(loanStatus) == 0
use something like this