Black Lives Matter. Please consider donating to Black Girls Code today.

Use list as value in RadioItems

Hey all,
This is my problem: I have a plot that’s connected to a multi-dropdown. Each selection is a country that is added to the plot.

The thing is, because there’s too many countries, I’d want to have RadioItems options that let you pre-populate the dropdown. Let’s say I want to have the option to prepopulate with countries from Europe. I tried with this:

countries= df[df.continent=='Europe'].country.unique()
options_radio = [{'label': 'European countries', 'value': countries.tolist()}]
options_countries = [{'label': i, 'value': i} for i in df.country.unique()]

    html.Div(dcc.RadioItems(id='pre-filter', options=options_radio)),
    html.Div('Seleccione países a graficar:'),

    html.Div(dcc.Dropdown(id='filter-plot',
                          options=options_countries,
                          multi=True
                          ), style={'margin-bottom': 15}),
    dcc.Graph(id='plot', style={'margin-top': 35}
              )

@app.callback(Output(component_id='filter-plot', component_property='value'),
              [Input(component_id='pre-filter', component_property='value')])
def link_radio_dropdown(value):
    return value

@app.callback(Output(component_id='plot', component_property='figure'),
              [Input(component_id='filter-plot', component_property='value')])
def plot(countries):
    etc
    return fig

I noticed this only works if the RadioItems component gets a string as value, but when I give it a list, it brings “Invalid argument options[0].value passed into RadioItems with ID “pre-filter”.”

What can I do? is there any workaround to this?

Thanks!

Hi @Juanouo, the value of a RadioItems can only be a string or a number, but you can use a json string to encode the list, and decode it in your callback as in the code below:

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import json

app = dash.Dash(__name__)

json_str = json.dumps([1, 2, 3])

app.layout = html.Div([
            dcc.RadioItems(
                id='radio',
                options=[{'label':'bundle', 'value':json_str}]
            ),
            dcc.Dropdown(id='dropdown', multi=True,
                options=[{'label':i, 'value':i} for i in range(10)])
])

@app.callback(Output('dropdown', 'value'),
            [Input('radio', 'value')])
def update_dropdown(val):
    if val is None:
        return dash.no_update
    return json.loads(val)


if __name__ == '__main__':
    app.run_server(debug=True)

Hey @Emmanuelle! Would this work with synced dropdowns? I managed to do it with a “;” separated string that I then proceeded to split, but because my dropdowns where synced (based on this answer ) I got a multiple calls to one id error.