Cannot get multiple inputs and multiple outputs to work

Hello,

I’m trying to create a graph with multiple (between 1 and 4) inputs from a dropdown.
I would like to have as many Bars as there are inputs in said graph. Unfortunately I can’t seem to get it to work.

When I create the graph “manually”, by having a list of bars in a list and then calling it:
(I’ve shown only the relevant parts of the code, I have the app.layout, all the necessary divs etc.)

departments = ['ladies','mens','accessories','kids']
output = []
for dep in departments:
    output.append(
         go.Bar(
             name = dep,
             x = categories[(categories.category == dep)]['sales']
     ))
dcc.Graph(figure = go.Figure(data = output))

Works as expected, graphs the bars.

I tried moving to having callbacks with a drop-down list of departments:

dcc.Dropdown(
			id = 'departament_b',
			options =[
				{'label': 'Ladies', 'value': 'ladies'},
				{'label': 'Mens', 'value': 'mens'},
				{'label': 'Accessories', 'value': 'accessories'},
				{'label': 'Kids', 'value': 'kids'}
			],
			value = ['ladies','mens','accessories','kids'],
			multi = True
		)
,
dcc.Graph(id = 'kategorie-sls')

Then I have my callback:

@app.callback(
[Output('kategorie-sls', 'figure')],
[Input('departament_b', 'value')]
)

And a function to update the graph:

def categories-sales(department_b):
    graph = []
    for dep in department_b:
        graph.append(go.Bar(
            name = dep,
            x = categories[(categories.category == dep)]['sales']
        ))

And I get the error:

dash.exceptions.InvalidCallbackReturnValue: Invalid number of output values for ..kategorie-sls.figure...

Expected 1 got 4

And if I select 1 value from drop-down (or change it to not multi and put only 1 value in value = [‘ladies’] I get this error:

Failed component prop type: Invalid component prop `figure` key `name` supplied to Graph. Bad object: { 
"name": "ladies", "x": [ 18535.059999999998 ], "type": "bar" } Valid keys: [ "data", "layout", "frames" ]

*(This error originated from the built-in JavaScript code that runs Dash apps. Click to see the full stack trace 
 or open your browser's console.)*

I’ve tried putting the output in a dictionary:

return {'data' : graph}

But then I just get an error how the output should be a list or a tuple…

Is what I’m trying to achieve even possible?

Welcome @rbw - you’re super close!

If you define the callback output as a list
@app.callback([Output('kategorie-sls', 'figure')], ...)
then the return value must also be a length-1 list like
return [go.Figure(data=graph)]
or
return [{'data': graph}]

But if you don’t wrap in a list
@app.callback(Output('kategorie-sls', 'figure'), ...)
you should also not wrap the return in a list
return go.Figure(data=graph)
or
return {'data': graph}

2 Likes

Awesome, thank you @alexcjohnson!
Now works as I thought it would.

Have a nice day!