Reputation: 47
I'd like to create multiple similar histograms in my Dash layout with a single callback output to a single div instead of repetitively copying and pasting code. Below is an example of my current code:
# In app.layout
html.Div([
html.H3('Plots'),
html.Div(dcc.Graph(id='A')),
html.Div(dcc.Graph(id='B')),
html.Div(dcc.Graph(id='C'))
])
# Callback
@app.callback(
[Output('A', 'figure'),
Output('B', 'figure'),
Output('C', 'figure')]
[Input('filtered-data-hidden', 'children')]
)
def plot_data(df):
dff = pd.read_json(df, orient='split')
figure_a = px.histogram(dff, x="A", nbins=20)
figure_b = px.histogram(dff, x="B", nbins=20)
figure_c = px.histogram(dff, x="C", nbins=20)
return figure_a, figure_b, figure_c
I tried the following:
# In app.layout
html.Div([
html.H3('Plots'),
html.Div(dcc.Graph(id='figures'))
])
# Callback
@app.callback(
Output('figures', 'figure'),
[Input('filtered-data-hidden', 'children')]
)
def plot_data(df):
dff = pd.read_json(df, orient='split')
figures = []
for feature in FEATURES.keys():
figures.append(px.histogram(dff, x=features, nbins=20))
return figures
But got an error:
Invalid argument `figure` passed into Graph with ID "figures".
Expected `object`.
Was supplied type `array`.
Upvotes: 0
Views: 1213
Reputation: 15722
You've left out some implementation details in your question so I will give more general examples here to highlight an approach you could take.
An idea is to dynamically create lists of elements based on your keys something like this:
graphs_from_keys = [dcc.Graph(id=key) for key in keys]
outputs_from_keys = [Output(key, "figure") for key in keys]
figures_from_keys = [px.histogram(df, x=key, nbins=20) for key in keys]
This allows us to pass each graph in the graphs_from_keys
list to the layout like this:
app.layout = html.Div(
[
html.H3("Plots"),
*graphs_from_keys,
# ...
]
)
and then the callback could look something like this:
@app.callback(
outputs_from_keys,
[Input('filtered-data-hidden', 'children')],
)
def plot_data(df):
# ...
return figures_from_keys
Upvotes: 2