简体   繁体   English

Plotly 破折号:图表未根据下拉选择更新

[英]Plotly Dash: Graphs not updating based on Dropdown selection

Although my dashboard got successfully created, it only shows the same line graph 5 times.尽管我的仪表板已成功创建,但它只显示了 5 次相同的折线图。 As the code shows, it should show line, pie and bar graphs as well as a map.如代码所示,它应该显示折线图、饼图和条形图以及 map。 The data does change year by year and by the different reports, but graphs stay the same.数据确实会逐年变化,并且会因不同的报告而变化,但图表保持不变。 To put it simply, the dashboard shows 4 line graphs while all the graphs should be different types of graphs.简而言之,仪表板显示了 4 个折线图,而所有的图都应该是不同类型的图。

Code below:下面的代码:

# Import required libraries
import pandas as pd
import dash
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output, State
import plotly.graph_objects as go
import plotly.express as px
from dash import no_update


# Create a dash application
app = dash.Dash(__name__)

# REVIEW1: Clear the layout and do not display exception till callback gets executed
app.config.suppress_callback_exceptions = True

# Read the airline data into pandas dataframe
airline_data =  pd.read_csv('https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMDeveloperSkillsNetwork-DV0101EN-SkillsNetwork/Data%20Files/airline_data.csv', 
                            encoding = "ISO-8859-1",
                            dtype={'Div1Airport': str, 'Div1TailNum': str, 
                                   'Div2Airport': str, 'Div2TailNum': str})


# List of years 
year_list = [i for i in range(2005, 2021, 1)]

"""Compute graph data for creating yearly airline performance report 

Function that takes airline data as input and create 5 dataframes based on the grouping condition to be used for plottling charts and grphs.

Argument:
     
    df: Filtered dataframe
    
Returns:
   Dataframes to create graph. 
"""
def compute_data_choice_1(df):
    # Cancellation Category Count
    bar_data = df.groupby(['Month','CancellationCode'])['Flights'].sum().reset_index()
    # Average flight time by reporting airline
    line_data = df.groupby(['Month','Reporting_Airline'])['AirTime'].mean().reset_index()
    # Diverted Airport Landings
    div_data = df[df['DivAirportLandings'] != 0.0]
    # Source state count
    map_data = df.groupby(['OriginState'])['Flights'].sum().reset_index()
    # Destination state count
    tree_data = df.groupby(['DestState', 'Reporting_Airline'])['Flights'].sum().reset_index()
    return bar_data, line_data, div_data, map_data, tree_data


"""Compute graph data for creating yearly airline delay report

This function takes in airline data and selected year as an input and performs computation for creating charts and plots.

Arguments:
    df: Input airline data.
    
Returns:
    Computed average dataframes for carrier delay, weather delay, NAS delay, security delay, and late aircraft delay.
"""
def compute_data_choice_2(df):
    # Compute delay averages
    avg_car = df.groupby(['Month','Reporting_Airline'])['CarrierDelay'].mean().reset_index()
    avg_weather = df.groupby(['Month','Reporting_Airline'])['WeatherDelay'].mean().reset_index()
    avg_NAS = df.groupby(['Month','Reporting_Airline'])['NASDelay'].mean().reset_index()
    avg_sec = df.groupby(['Month','Reporting_Airline'])['SecurityDelay'].mean().reset_index()
    avg_late = df.groupby(['Month','Reporting_Airline'])['LateAircraftDelay'].mean().reset_index()
    return avg_car, avg_weather, avg_NAS, avg_sec, avg_late


# Application layout
app.layout = html.Div(children=[html.H1 ('US Domestic Airline Flights Performance', style={'textAlign': 'center', 'color': '#503D36','font-size': 40}),
                                # TASK1: Add title to the dashboard
                                # Enter your code below. Make sure you have correct formatting.
                                 
                                
                                
                                # REVIEW2: Dropdown creation
                                # Create an outer division 
                                html.Div([
                                    # Add an division
                                    html.Div([
                                        # Create an division for adding dropdown helper text for report type
                                        html.Div(
                                            [
                                            html.H2('Report Type:', style={'margin-right': '2em'}),
                                            ]
                                        ),
                                        # TASK2: Add a dropdown
                                        # Enter your code below. Make sure you have correct formatting.
                                        dcc.Dropdown(id='input-type', 
                                                     options=[{'label': 'Yearly Airline Performance Report', 'value': '.OPT1'},{'label': 'Yearly Airline Delay Report', 'value': 'OPT2'}],
                                                           
                                                                                              
                                                     placeholder='Select a report type',
                                                     style={'width':'80%', 'padding':'3px', 'font-size': '20px', 'text-align-last' : 'center'})
                                    # Place them next to each other using the division style
                                    ], style={'display':'flex'}),
                                    
                                   # Add next division 
                                   html.Div([
                                       # Create an division for adding dropdown helper text for choosing year
                                        html.Div(
                                            [
                                            html.H2('Choose Year:', style={'margin-right': '2em'})
                                            ]
                                        ),
                                        dcc.Dropdown(id='input-year', 
                                                     # Update dropdown values using list comphrehension
                                                     options=[{'label': i, 'value': i} for i in year_list],
                                                     placeholder="Select a year",
                                                     style={'width':'80%', 'padding':'3px', 'font-size': '20px', 'text-align-last' : 'center'}),
                                            # Place them next to each other using the division style
                                            ], style={'display': 'flex'}),  
                                          ]),
                                
                                # Add Computed graphs
                                # REVIEW3: Observe how we add an empty division and providing an id that will be updated during callback
                                html.Div([ ], id='plot1'),
    
                                html.Div([
                                        html.Div([ ], id='plot2'),
                                        html.Div([ ], id='plot3')
                                ], style={'display': 'flex'}),
                                
                                # TASK3: Add a division with two empty divisions inside. See above disvision for example.
                                # Enter your code below. Make sure you have correct formatting.
                                html.Div([
                                        html.Div([ ], id='plot4'),
                                        html.Div([ ], id='plot5')
                                ], style={'display': 'flex'}),
                                ])

# Callback function definition
# TASK4: Add 5 ouput components
# Enter your code below. Make sure you have correct formatting.
@app.callback( [Output(component_id='plot1', component_property='children')],
 [Output('plot2','children'),
  Output('plot3','children'),
  Output('plot4','children'),
  Output('plot5','children')],
               [Input(component_id='input-type', component_property='value'),
                Input(component_id='input-year', component_property='value')],
               # REVIEW4: Holding output state till user enters all the form information. In this case, it will be chart type and year
               [State("plot1", 'children'), State("plot2", "children"),
                State("plot3", "children"), State("plot4", "children"),
                State("plot5", "children")
               ])
# Add computation to callback function and return graph
def get_graph(chart, year, children1, children2, c3, c4, c5):
      
        # Select data
        df =  airline_data[airline_data['Year']==int(year)]
       
        if chart == 'OPT1':
            # Compute required information for creating graph from the data
            bar_data, line_data, div_data, map_data, tree_data = compute_data_choice_1(df)
            
            # Number of flights under different cancellation categories
            bar_fig = px.bar(bar_data, x='Month', y='Flights', color='CancellationCode', title='Monthly Flight Cancellation')
            
            # TASK5: Average flight time by reporting airline
            # Enter your code below. Make sure you have correct formatting.
            
            line_fig = px.line(line_data, x='Month', y='AirTime', color='Reporting Airline', title='Average monthly flight time (minutes) by airline')
            # Percentage of diverted airport landings per reporting airline
            pie_fig = px.pie(div_data, values='Flights', names='Reporting_Airline', title='% of flights by reporting airline')
            
            # REVIEW5: Number of flights flying from each state using choropleth
            map_fig = px.choropleth(map_data,  # Input data
                    locations='OriginState', 
                    color='Flights',  
                    hover_data=['OriginState', 'Flights'], 
                    locationmode = 'USA-states', # Set to plot as US States
                    color_continuous_scale='GnBu',
                    range_color=[0, map_data['Flights'].max()]) 
            map_fig.update_layout(
                    title_text = 'Number of flights from origin state', 
                    geo_scope='usa') # Plot only the USA instead of globe
            
            # TASK6: Number of flights flying to each state from each reporting airline
            # Enter your code below. Make sure you have correct formatting.
            
            tree_fig = px.treemap(tree_data, path=['DestState', 'Reporting_Airline'], 
                      values='Flights',
                      color='Flights',
                      color_continuous_scale='RdBu',
                      title='Flight count by airline to destination state'
                )
            
            # REVIEW6: Return dcc.Graph component to the empty division
            return [dcc.Graph(figure=tree_fig), 
                    dcc.Graph(figure=pie_fig),
                    dcc.Graph(figure=map_fig),
                    dcc.Graph(figure=bar_fig),
                    dcc.Graph(figure=line_fig)
                   ]
        else:
            # REVIEW7: This covers chart type 2 and we have completed this exercise under Flight Delay Time Statistics Dashboard section
            # Compute required information for creating graph from the data
            avg_car, avg_weather, avg_NAS, avg_sec, avg_late = compute_data_choice_2(df)
            
            # Create graph
            carrier_fig = px.line(avg_car, x='Month', y='CarrierDelay', color='Reporting_Airline', title='Average carrrier delay time (minutes) by airline')
            weather_fig = px.line(avg_weather, x='Month', y='WeatherDelay', color='Reporting_Airline', title='Average weather delay time (minutes) by airline')
            nas_fig = px.line(avg_NAS, x='Month', y='NASDelay', color='Reporting_Airline', title='Average NAS delay time (minutes) by airline')
            sec_fig = px.line(avg_sec, x='Month', y='SecurityDelay', color='Reporting_Airline', title='Average security delay time (minutes) by airline')
            late_fig = px.line(avg_late, x='Month', y='LateAircraftDelay', color='Reporting_Airline', title='Average late aircraft delay time (minutes) by airline')
            
            return[dcc.Graph(figure=carrier_fig), 
                   dcc.Graph(figure=weather_fig), 
                   dcc.Graph(figure=nas_fig), 
                   dcc.Graph(figure=sec_fig), 
                   dcc.Graph(figure=late_fig)]


# Run the app
if __name__ == '__main__':
    app.run_server(debug=True, use_reloader=False)

There are two typos in your code:您的代码中有两个错别字:

  • In the list of options of the dropdown with id='input-type' the value of the first option is set to '.OPT1' instead of 'OPT1' , which is why the callback always returns the output corresponding to 'OPT2' , ie it always returns the line charts.id='input-type'下拉列表的选项列表中,第一个选项的值设置为'.OPT1'而不是'OPT1' ,这就是为什么回调总是返回对应于'OPT2' ,即它总是返回折线图。
  • In the definition of line_fig under 'OPT1' the color is set equal to 'Reporting Airline' instead of 'Reporting_Airline' .'OPT1'下的line_fig定义中, color设置为'Reporting Airline'而不是'Reporting_Airline'

Note also that there is no need to include the children of 'plot1' , 'plot2' , 'plot3' , 'plot4' and 'plot5' as State in the callback.另请注意,没有必要在回调中包含 ' children 'plot1''plot2''plot3''plot4''plot5'作为State的子级。

Updated code:更新代码:

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

# Create a dash application
app = dash.Dash(__name__)

# Clear the layout and do not display exception till callback gets executed
app.config.suppress_callback_exceptions = True

# Read the airline data into pandas dataframe
airline_data = pd.read_csv(
    'https://cf-courses-data.s3.us.cloud-object-storage.appdomain.cloud/IBMDeveloperSkillsNetwork-DV0101EN-SkillsNetwork/Data%20Files/airline_data.csv',
    encoding='ISO-8859-1',
    dtype={'Div1Airport': str, 'Div1TailNum': str, 'Div2Airport': str, 'Div2TailNum': str}
)

# List of years
year_list = [i for i in range(2005, 2021, 1)]

def compute_data_choice_1(df):
    '''
    Function that takes airline data as input and create 5 dataframes based on the grouping condition to be used for plottling charts and grphs.

    Argument:
        df: Filtered dataframe

    Returns:
       Dataframes to create graph.
    '''
    # Cancellation Category Count
    bar_data = df.groupby(['Month', 'CancellationCode'])['Flights'].sum().reset_index()
    # Average flight time by reporting airline
    line_data = df.groupby(['Month', 'Reporting_Airline'])['AirTime'].mean().reset_index()
    # Diverted Airport Landings
    div_data = df[df['DivAirportLandings'] != 0.0]
    # Source state count
    map_data = df.groupby(['OriginState'])['Flights'].sum().reset_index()
    # Destination state count
    tree_data = df.groupby(['DestState', 'Reporting_Airline'])['Flights'].sum().reset_index()
    return bar_data, line_data, div_data, map_data, tree_data

def compute_data_choice_2(df):
    '''
    This function takes in airline data and selected year as an input and performs computation for creating charts and plots.

    Arguments:
        df: Input airline data.

    Returns:
        Computed average dataframes for carrier delay, weather delay, NAS delay, security delay, and late aircraft delay.
    '''
    avg_car = df.groupby(['Month', 'Reporting_Airline'])['CarrierDelay'].mean().reset_index()
    avg_weather = df.groupby(['Month', 'Reporting_Airline'])['WeatherDelay'].mean().reset_index()
    avg_NAS = df.groupby(['Month', 'Reporting_Airline'])['NASDelay'].mean().reset_index()
    avg_sec = df.groupby(['Month', 'Reporting_Airline'])['SecurityDelay'].mean().reset_index()
    avg_late = df.groupby(['Month', 'Reporting_Airline'])['LateAircraftDelay'].mean().reset_index()
    return avg_car, avg_weather, avg_NAS, avg_sec, avg_late

# Application layout
app.layout = html.Div(children=[

    html.H1(
        children='US Domestic Airline Flights Performance',
        style={'textAlign': 'center', 'color': '#503D36', 'font-size': 40}
    ),

    html.Div([

        html.Div([

            html.H2('Report Type:', style={'margin-right': '2em'}),

            dcc.Dropdown(
                id='input-type',
                options=[
                    {'label': 'Yearly Airline Performance Report', 'value': 'OPT1'},
                    {'label': 'Yearly Airline Delay Report', 'value': 'OPT2'}
                ],
                value='OPT1',
                placeholder='Select a report type',
                style={'width': '80%', 'padding': '3px', 'font-size': '20px', 'text-align-last': 'center'}
            )

        ], style={'display': 'flex'}),

        html.Div([

            html.H2('Choose Year:', style={'margin-right': '2em'}),

            dcc.Dropdown(
                id='input-year',
                options=[{'label': i, 'value': i} for i in year_list],
                value=year_list[0],
                placeholder='Select a year',
                style={'width': '80%', 'padding': '3px', 'font-size': '20px', 'text-align-last': 'center'}
            ),

        ], style={'display': 'flex'}),

    ]),

    html.Div(id='plot1'),

    html.Div(
        children=[
            html.Div(id='plot2'),
            html.Div(id='plot3')
        ],
        style={'display': 'flex'}
    ),

    html.Div(
        children=[
            html.Div(id='plot4'),
            html.Div(id='plot5')
        ],
        style={'display': 'flex'}
    ),

])

@app.callback([Output('plot1', 'children')],
              [Output('plot2', 'children'),
               Output('plot3', 'children'),
               Output('plot4', 'children'),
               Output('plot5', 'children')],
              [Input('input-type', 'value'),
               Input('input-year', 'value')])
def get_graph(chart, year):

    df = airline_data[airline_data['Year'] == int(year)]

    if chart == 'OPT1':

        bar_data, line_data, div_data, map_data, tree_data = compute_data_choice_1(df)

        bar_fig = px.bar(bar_data,
                         x='Month',
                         y='Flights',
                         color='CancellationCode',
                         title='Monthly Flight Cancellation')

        line_fig = px.line(line_data,
                           x='Month',
                           y='AirTime',
                           color='Reporting_Airline',
                           title='Average monthly flight time (minutes) by airline')

        pie_fig = px.pie(div_data,
                         values='Flights',
                         names='Reporting_Airline',
                         title='% of flights by reporting airline')

        map_fig = px.choropleth(map_data,
                                locations='OriginState',
                                color='Flights',
                                hover_data=['OriginState', 'Flights'],
                                locationmode='USA-states',
                                color_continuous_scale='GnBu',
                                range_color=[0, map_data['Flights'].max()])

        map_fig.update_layout(title_text='Number of flights from origin state',
                              geo_scope='usa')

        tree_fig = px.treemap(tree_data, path=['DestState', 'Reporting_Airline'],
                              values='Flights',
                              color='Flights',
                              color_continuous_scale='RdBu',
                              title='Flight count by airline to destination state')

        return [dcc.Graph(figure=tree_fig),
                dcc.Graph(figure=pie_fig),
                dcc.Graph(figure=map_fig),
                dcc.Graph(figure=bar_fig),
                dcc.Graph(figure=line_fig)]

    else:

        avg_car, avg_weather, avg_NAS, avg_sec, avg_late = compute_data_choice_2(df)

        carrier_fig = px.line(avg_car,
                              x='Month',
                              y='CarrierDelay',
                              color='Reporting_Airline',
                              title='Average carrrier delay time (minutes) by airline')

        weather_fig = px.line(avg_weather,
                              x='Month',
                              y='WeatherDelay',
                              color='Reporting_Airline',
                              title='Average weather delay time (minutes) by airline')

        nas_fig = px.line(avg_NAS,
                          x='Month',
                          y='NASDelay',
                          color='Reporting_Airline',
                          title='Average NAS delay time (minutes) by airline')

        sec_fig = px.line(avg_sec,
                          x='Month',
                          y='SecurityDelay',
                          color='Reporting_Airline',
                          title='Average security delay time (minutes) by airline')

        late_fig = px.line(avg_late,
                           x='Month',
                           y='LateAircraftDelay',
                           color='Reporting_Airline',
                           title='Average late aircraft delay time (minutes) by airline')

        return [dcc.Graph(figure=carrier_fig),
                dcc.Graph(figure=weather_fig),
                dcc.Graph(figure=nas_fig),
                dcc.Graph(figure=sec_fig),
                dcc.Graph(figure=late_fig)]

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM