pythonplotly-dashdash-bootstrap-components

Display interactive metrics within dbc.Card - Dash


I'm aiming to include interactive counts as metrics. Specifically, insert total sums within cards that will changed depending on the variable selected from a nav bar.

Using below, the Navbar is used to display the proportion of successes and failures as a pie chart. I want to use the corresponding sums of success_count and failure_count as a metric to be displayed as a number.

Is it possible to return these values and display them within the designated dbc.Card?

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import plotly.express as px
import plotly.graph_objs as go
import dash
from dash import dcc
from dash import html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output

# This dataframe has 244 lines, but 4 distinct values for `day`
url="https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBM-DS0321EN-SkillsNetwork/datasets/spacex_launch_dash.csv"

spacex_df = pd.read_csv(url)

spacex_df.rename(columns={'Launch Site':'Site'}, inplace=True)

external_stylesheets = [dbc.themes.SPACELAB, dbc.icons.BOOTSTRAP]

app = dash.Dash(__name__, external_stylesheets = external_stylesheets)

success_card = dbc.Card(
    [
        dbc.CardHeader("Some header"),
        dbc.CardBody(
            [
                html.H6("Success Count", className="card-title"),
                html.P("###total count of successes", className="card-text"),
            ]
        ),
    ],
    className='text-center m-4'
)

failure_card = dbc.Card(
    [
        dbc.CardHeader("Some header"),
        dbc.CardBody(
            [
                html.H6("Failure Count", className="card-title"),
                html.P("##total count of failures", className="card-text"),
            ]
        ),
    ],
    className='text-center m-4'
)

nav_bar =  html.Div([
     html.P("site-dropdown:"),
     dcc.Dropdown(
       id='Site', 
       value='Site', 
       options=[{'value': x, 'label': x} 
                for x in ['CCAFS LC-40', 'CCAFS SLC-40', 'KSC LC-39A', 'VAFB SLC-4E']],
       clearable=False
   ),
])


app.layout = dbc.Container([
    dbc.Row([
        dbc.Col(html.Div(nav_bar, className="bg-secondary h-100"), width=2),
        dbc.Col([
            dbc.Row([
                dbc.Col(success_card),
            ]),
            dbc.Row([
                dbc.Col(dcc.Graph(id = 'pie-chart'), style={
                        "padding-bottom": "10px",
                    },),
            ]),
            dbc.Row([
                # insert pie chart
                dbc.Col(dcc.Graph(id = "bar-chart")),
            ]),
        ], width=5),
        dbc.Col([
            dbc.Row([
                dbc.Col(failure_card),
            ]),
            dbc.Row([
                # insert bar chart
                dbc.Col(dcc.Graph()),
            ], className="h-100"),
        ], width=5),
    ])
], fluid=True)


@app.callback(
    Output("pie-chart", "figure"), 
    [Input("Site", "value")])

def generate_chart(value):
    pie_data = spacex_df[spacex_df['Site'] == value]
    success_count = sum(pie_data['class'] == 0)
    failure_count = sum(pie_data['class'] == 1)
    fig = go.Figure(data=[go.Pie(labels=['success','failure'], values=[success_count, failure_count])])
    fig.update_layout(title=f"Site: {value}")
    
    return fig

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

Solution

  • You should use html.Div in your card with id and then return html.P in this Div. Something as below:

    import pandas as pd
    import numpy as np
    import matplotlib.pyplot as plt
    import plotly.express as px
    import plotly.graph_objs as go
    import dash
    from dash import dcc
    from dash import html
    import dash_bootstrap_components as dbc
    from dash.dependencies import Input, Output
    
    # This dataframe has 244 lines, but 4 distinct values for `day`
    url="https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBM-DS0321EN-SkillsNetwork/datasets/spacex_launch_dash.csv"
    
    spacex_df = pd.read_csv(url)
    
    spacex_df.rename(columns={'Launch Site':'Site'}, inplace=True)
    
    external_stylesheets = [dbc.themes.SPACELAB, dbc.icons.BOOTSTRAP]
    
    app = dash.Dash(__name__, external_stylesheets = external_stylesheets)
    
    success_card = dbc.Card(
        [
            dbc.CardHeader("Some header"),
            dbc.CardBody(
                [
                    html.H6("Success Count", className="card-title"),
                    html.Div(id='count_of_success'),
                ]
            ),
        ],
        className='text-center m-4'
    )
    
    failure_card = dbc.Card(
        [
            dbc.CardHeader("Some header"),
            dbc.CardBody(
                [
                    html.H6("Failure Count", className="card-title"),
                    html.Div(id='count_of_failure'),
                ]
            ),
        ],
        className='text-center m-4'
    )
    
    nav_bar =  html.Div([
         html.P("site-dropdown:"),
         dcc.Dropdown(
           id='Site', 
           value='Site', 
           options=[{'value': x, 'label': x} 
                    for x in ['CCAFS LC-40', 'CCAFS SLC-40', 'KSC LC-39A', 'VAFB SLC-4E']],
           clearable=False
       ),
    ])
    
    
    app.layout = dbc.Container([
        dbc.Row([
            dbc.Col(html.Div(nav_bar, className="bg-secondary h-100"), width=2),
            dbc.Col([
                dbc.Row([
                    dbc.Col(success_card),
                ]),
                dbc.Row([
                    dbc.Col(dcc.Graph(id = 'pie-chart'), style={
                            "padding-bottom": "10px",
                        },),
                ]),
                dbc.Row([
                    # insert pie chart
                    dbc.Col(dcc.Graph(id = "bar-chart")),
                ]),
            ], width=5),
            dbc.Col([
                dbc.Row([
                    dbc.Col(failure_card),
                ]),
                dbc.Row([
                    # insert bar chart
                    dbc.Col(dcc.Graph()),
                ], className="h-100"),
            ], width=5),
        ])
    ], fluid=True)
    
    
    @app.callback(
        [Output("pie-chart", "figure"),
        Output("count_of_success", "children"),
        Output("count_of_failure", "children")], 
        [Input("Site", "value")])
    
    def generate_chart(value):
        pie_data = spacex_df[spacex_df['Site'] == value]
        success_count = sum(pie_data['class'] == 0)
        failure_count = sum(pie_data['class'] == 1)
        fig = go.Figure(data=[go.Pie(labels=['success','failure'], values=[success_count, failure_count])])
        fig.update_layout(title=f"Site: {value}")
        
        return fig, html.P(f'###total count of successes are: {success_count}'), html.P(f'###total count of failure are: {failure_count}')
    
        
    if __name__ == '__main__':
        app.run_server(debug=False)
    

    And here is the result:

    enter image description here