✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
🧬 Learn how to build RNA-Seq data apps with Python & Dash. Register for the May 20 Webinar!

Multi drop box selection for plot generation

Hi There:

I know how **kwargs is used in Python for variable number of input arguments.

My objective is to have a few options in a multi drop box selection. I wrote a method and call back. What i have working so far is when i choose each of those single options, the graph populates correctly. When I choose 2 or more, nothing happens - this is because my input for the method is “Selection” - this is not right because then it think it just has 1 input. How do I specify **kwargs correctly here?

@rookie - Could you create a small, simple reproducable example that shows your code and what isn’t working? That will be the easiest way for the community to help you out :+1:. Here’s some more info on how to create a minimal, complete, and verifiable example: https://stackoverflow.com/help/mcve

dcc.Graph(
        id='example-graph-2',
        figure={
            'data': [ 
                {'x': ['1', '2', '3', '4'], 'y': [4,1,2,1.5], 'type':'bar', 'name': 'A'},
                {'x': ['6.1, '6.1', '6.2', '6.3'], 'y': [2,4,5, 3.1], 'type':'bar', 'name': 'B'},
                {'x': ['9.0', '9.1', '9.2', '8.3'], 'y': [1,1,2, 2.9], 'type':'bar', 'name': 'C'},
                {'x': ['14.0', '14.1', '14.2', 1'4.3'], 'y': [0.9,4,5, 1.2], 'type':'bar', 'name': 'D'},
            ],
            'layout': {
                'plot_bgcolor': colors['background'],
                'paper_bgcolor': colors['background'],
                'font': {
                    'color': colors['text']
                }
            }
        }
    )
@app.callback(
              dash.dependencies.Output('example-graph-2', 'figure'),
              [dash.dependencies.Input('Selection', 'value')])

def  update_multi_graph(Selection):
    if Selection == ['A, 'B', 'C', 'D']:
        return { 'data' : [go.Bar({'x': ['1', '2', '3', '4'], 'y': [4,1,2,1.5], 'type':'bar', 'name': 'A'},
                {'x': ['6.1, '6.1', '6.2', '6.3'], 'y': [2,4,5, 3.1], 'type':'bar', 'name': 'B'},
                {'x': ['9.0', '9.1', '9.2', '8.3'], 'y': [1,1,2, 2.9], 'type':'bar', 'name': 'C'},
                {'x': ['14.0', '14.1', '14.2', 1'4.3'], 'y': [0.9,4,5, 1.2], 'type':'bar', 'name': 'D'},                   
               hoverinfo='label+value+percent',
                         #textinfo='yes'
                         )],
                 'layout' : go.Layout(
                         title='Results',
                         showlegend=True,
                         legend=go.Legend(
                                          x=0,
                                          y=1.0
                                          ),
                         margin=go.Margin(l=40, r=0, t=40, b=30)
                         )
        }
    elif Selection == ['A']:
        return { 'data' : [go.Bar({'x': ['1', '2', '3', '4'], 'y': [4,1,2,1.5], 'type':'bar', 'name': 'A'},
                              hoverinfo='label+value+percent',
                              #textinfo='yes'
                              )],
                 'layout' : go.Layout(
                            title='Results',
                            showlegend=True,
                            legend=go.Legend(
                                             x=0,
                                             y=1.0
                                             ),
                           margin=go.Margin(l=40, r=0, t=40, b=30)
                           )
         }

And such is for B, C, D but i could have combination like AB, BCD… and such.

If my X-axes has [1, 2, 3, 4] and if i chose options A, B, C, D from the multi drop down. 4 graphs should be seen for each value on the X-axes and based on my change of selection, it should reflect there as well.

@app.callback(
              dash.dependencies.Output('example-graph-2', 'figure'),
              [dash.dependencies.Input('Selection', 'value'),
               dash.dependencies.Input('Selection', 'value'),
               dash.dependencies.Input('Selection', 'value'),
               dash.dependencies.Input('Selection', 'value')])

I guess if there is a way to tell this Input that there are any number of input variables between 0 and 4 then my problem would be solved. I still would like to know how to specify variable number of args to the “update_multi_graph()”

The python syntax for specifying a variable number of arguments is *args (see https://pythontips.com/2013/08/04/args-and-kwargs-in-python-explained/). I’m not sure if that will be helpful in this case though, because Dash will always pass in values for the number of Input and State elements that you have specified in the @app.callback decorator.


It sounds like what you want to do here is check for None - If no value is selected in a dcc.Dropdown, then the value of that dropdown will be None. None is also the default value of value if it is not specified in the layout.

For example,

app.layout = dcc.Dropdown(
    id='my-dropdown',
    options=[{'label': 'a', 'value': 'a'}]
)

Is equivalent to

app.layout = dcc.Dropdown(
    id='my-dropdown',
    options=[{'label': 'a', 'value': 'a'}],
    value=None
)

So, you can check for these values in your function to see if they are selected:

@app.callback(
              dash.dependencies.Output('example-graph-2', 'figure'),
              [dash.dependencies.Input('Selection-1', 'value'),
               dash.dependencies.Input('Selection-2', 'value'),
               dash.dependencies.Input('Selection-3', 'value'),
               dash.dependencies.Input('Selection-4', 'value')])
def update_graph(value_1, value_2, value_3, value_4):
    data = []
    if value_1 is not None:
       # create the first graph
       data.append({'x': ..., 'y': ..., 'name': value_1})

    if value_2 is not None:
       # create the second graph
       data.append({'x': ..., 'y': ..., 'name': value_2})

    if value_3 is not None:
       # create the third graph
       data.append({'x': ..., 'y': ..., 'name': value_3})

    if value_4 is not None:
       # create the third graph
       data.append({'x': ..., 'y': ..., 'name': value_4})

    return {'data': data, 'layout': {}}