runningbirds
runningbirds

Reputation: 6605

Produce multiple plots using dash callbacks

I'm not clear how I could dynamically create multiple charts at once - or if that is not possible then how I could loop through a list of values using a single callback.

For example in the code below list of continents is a a list of filter options. Is it possible to basically make it so when this page loads, I see 5 charts automatically?

Currently, what I'm doing is I have to type 5 @app.callback...make_scatter_plot(option=_dropdown_value) which ends up with a million lines of code in my file and makes it hard to read even though everything is doing the same thing.

What am I missing? Thanks

from dash import Dash, dcc, html, Input, Output
import plotly.express as px
import pandas as pd 
import numpy as np 

app = Dash(__name__)

df = px.data.gapminder()

list_of_continents = ["Asia", "Africa", "Europe", 'Oceania', 'Americas']
app.layout = html.Div([
    html.H4('Restaurant tips by day of week'),
    dcc.Dropdown(
        id="dropdown",
        options=list_of_continents,

        multi=False
    ),
    dcc.Graph(id="graph"),
    #dcc.Graph(id ='graph2') ##???? 
])


@app.callback(
    Output("graph", "figure"),
    Input("dropdown", "value")
    )
def make_scatter_plot(  value =[i for i in list_of_continents], df = df):
    """
    
    """
    data = df[df['continent'].isin([value])]
    
    fig = px.scatter(data, x="lifeExp", y="gdpPercap", 
                 size="pop")
    return fig


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

Upvotes: 1

Views: 2368

Answers (1)

Waleed Malik
Waleed Malik

Reputation: 366

although plotly express can help you set up a graph with just one line of code it’s not very handy when it comes to customizing each trace. So, for that, you’ve to switch to graphs_objects.
In the following lines of code, the callback generates a Graph component for each trace and appends each graph component to a Div component. Hence you get multiple graphs using a single callback.

from dash import Dash, dcc, html, Input, Output
import plotly.express as px
import plotly.graph_objects as go
import pandas as pd 
import numpy as np 

app = Dash(__name__)

df = px.data.gapminder()


app.layout = html.Div([
    html.H4('Restaurant tips by day of week'),

    html.Div(id='graphs',children=[])
   
])


@app.callback(
    Output("graphs", "children"),
    Input("graphs", "children")
    )
def make_scatter_plot(child):
    """
    
    """

    for continent in df['continent'].unique():
        df_filtered = df[df['continent'] == continent]
        fig = go.Figure()
        fig.add_trace(
            go.Scatter(x = df_filtered['lifeExp'],
                       y = df_filtered['gdpPercap'],
                       mode = 'markers',
                       marker = dict(size = 10 + (df_filtered['pop'] - df_filtered['pop'].min()) * 20 
                       / (df_filtered['pop'].max() - df_filtered['pop'].min())) # This is just to scale the marker size value between 10 and 20. 
                       )
            )
        fig.update_layout(
            title_text = continent
        )
        child.append(dcc.Graph(figure=fig))


    return child


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

The output of the Code: Click here

Upvotes: 2

Related Questions