Search code examples
pythonplotplotlyplotly-dashdashboard

Another dash/plotly dilemma


I hate to keep posting about dash\plotly but I cant understand what is going wrong here. I have copied and pasted from the plotly site the code in order to display a pie chart with a drop down menu. When I create the dashboard there is a dropdown menu that shows all the categories but there is no pie chart to be seen. Please help me to understand what is going wrong. Code below:

import pandas as pd
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.express as px

# 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)

app = dash.Dash(__name__)

app.layout = 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
    ),
   
    dcc.Graph(id="pie-chart"),
])

@app.callback(
    Output("pie-chart", "figure"), 
    [Input("Launch Site", "value")])
def generate_chart(Site, values):
    fig = px.pie(spacex_df, values='Site', names='Site')
    return fig

app.run_server()

Solution

  • I think the main issues with your code were that your generate_chart function had two arguments, but the @app.callback decorator had only one input argument, and that for the values argument in px.pie, you need to pass a column name whose values can be summed together. One issue with using px.pie in this case is that if you sum the values in the 'class' column, the 0s for success will always sum to 0.

    Since you explained in your comment that what you really want to display in your pie chart is the count of successes and failures (which are 0s and 1s in the 'class' column), I thought it would be easiest to sum up the number of 0s and 1s for the particular 'Site', and pass the arguments labels=['success','failure'] and values=[success_count, failure_count] to go.Pie.

    import pandas as pd
    import dash
    from dash import html, dcc
    from dash.dependencies import Input, Output
    import plotly.graph_objects as go
    import plotly.express as px
    
    # 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)
    
    app = dash.Dash(__name__)
    
    app.layout = 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
        ),
       
        dcc.Graph(id="pie-chart"),
    ])
    
    @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)
    

    enter image description here