Plotly Dash:图表未根据下拉选择更新

     2023-02-18     44

关键词:

【中文标题】Plotly Dash:图表未根据下拉选择更新【英文标题】:Plotly Dash: Graphs not updating based on Dropdown selection 【发布时间】:2022-01-08 00:46:17 【问题描述】:

虽然我的仪表板已成功创建,但它只显示相同的折线图 5 次。如代码所示,它应该显示折线图、饼图和条形图以及地图。数据确实会逐年变化,并且会因不同的报告而变化,但图表保持不变。简单来说,仪表板显示了 4 个折线图,而所有的图都应该是不同类型的图。

代码如下:

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

【问题讨论】:

【参考方案1】:

您的代码中有两个错别字:

id='input-type'下拉列表的选项列表中,第一个选项的值设置为'.OPT1'而不是'OPT1',这就是为什么回调总是返回与'OPT2'对应的输出,即它总是返回折线图。 在'OPT1'line_fig 的定义中,color 设置为等于'Reporting Airline',而不是'Reporting_Airline'

另请注意,在回调中无需将'plot1''plot2''plot3''plot4''plot5' 中的children 包括为State

更新代码:

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

【讨论】:

根据 python plotly dash 中先前单选项目/下拉列表中的选择禁用下拉列表

】根据pythonplotlydash中先前单选项目/下拉列表中的选择禁用下拉列表【英文标题】:disablingadropdownbasedonchoiceinpreviousradioitem/dropdowninpythonplotlydash【发布时间】:2022-01-0905:26:26【问题描述】:我有3个链接的下拉列表,但我希望根据... 查看详情

带有一个下拉列表和多个选择器的 Plotly Dash 散点图(全部)

】带有一个下拉列表和多个选择器的PlotlyDash散点图(全部)【英文标题】:PlotlyDashScatterplotwithonedropdownandmultipleselector(all)【发布时间】:2021-10-2810:25:02【问题描述】:我正在尝试使用一个下拉选择器创建散点图,并希望选择器... 查看详情

Plotly Dash:为啥我的图形无法通过多个下拉选择显示?

】PlotlyDash:为啥我的图形无法通过多个下拉选择显示?【英文标题】:PlotlyDash:Whyismyfigurefailingtoshowwithamultidropdownselection?PlotlyDash:为什么我的图形无法通过多个下拉选择显示?【发布时间】:2020-09-1220:43:42【问题描述】:我正... 查看详情

如何通过 Python 中的 Plotly 从 Dash 的下拉列表中选择数据集列?

】如何通过Python中的Plotly从Dash的下拉列表中选择数据集列?【英文标题】:HowtoselectdatasetcolumnfromdropdowninDashbyPlotlyinPython?【发布时间】:2020-03-1908:19:43【问题描述】:我希望获得一些关于在Python中使用DashbyPlotly创建仪表板的指导... 查看详情

Plotly Dash 回调错误更新输出图

】PlotlyDash回调错误更新输出图【英文标题】:PlotlyDashCallbackerrorupdatingOutputGraph【发布时间】:2020-02-1519:03:19【问题描述】:我正在尝试使用PlotlyDash创建交互式图表。该代码从用户处读取交易品种名称,并从yahooFinance中提取历史... 查看详情

Dash Plotly:如何使用 DatePickerRange 按日期过滤数据框?

】DashPlotly:如何使用DatePickerRange按日期过滤数据框?【英文标题】:DashPlotly:HowtofilterDataFramebydatewithDatePickerRange?【发布时间】:2021-12-2123:21:53【问题描述】:我使用DashPlotly进行数据可视化。我已经有了显示正确数据的数据框和... 查看详情

Plotly Dash:下拉组件回调可见性错误

】PlotlyDash:下拉组件回调可见性错误【英文标题】:PlotlyDash:Dropdowncomponentcallbackvisibilitybug【发布时间】:2020-07-3020:41:44【问题描述】:我最近一直在使用Dash开发一个应用程序。该应用程序使用了许多控件,例如核心组件中的Inp... 查看详情

Python Plotly Dash 下拉列表为散点图添加“全选”

】PythonPlotlyDash下拉列表为散点图添加“全选”【英文标题】:PythonPlotlyDashdropdownAddinga"selectall"forscatterplot【发布时间】:2021-10-2821:37:28【问题描述】:我想为我的下拉列表添加一个全选,并在应用程序打开时将其设为默... 查看详情

Plotly-Dash 实时图表:回调失败

】Plotly-Dash实时图表:回调失败【英文标题】:Plotly-Dashlivechart:Callbackfailed【发布时间】:2021-09-1017:46:23【问题描述】:不久前我一直在研究Plotly-Dash库。第二张图有回调问题..我不知道是什么原因。我对组件了解了很长时间,但... 查看详情

如何命名 Dash/Plotly 中的下拉菜单

】如何命名Dash/Plotly中的下拉菜单【英文标题】:HowtonametothedropdownmenuinDash/Plotly【发布时间】:2020-12-2708:27:43【问题描述】:我对dash很陌生,我正在尝试弄清楚如何将名称放在下拉菜单和滑块上方,并在它们之间提供一些间隙。... 查看详情

如何在具有多个唯一图形的布局上实现 Dash/Plotly 清单持久性?

】如何在具有多个唯一图形的布局上实现Dash/Plotly清单持久性?【英文标题】:HowdoIimplementDash/Plotlychecklistpersistenceonalayoutwithmultipleuniquegraphs?【发布时间】:2021-11-2518:45:10【问题描述】:我的仪表板有一个2x2的图表布局,每个图... 查看详情

Plotly-Dash 未显示图形元素列表

】Plotly-Dash未显示图形元素列表【英文标题】:Plotly-Dashnotshowinglistofgraphelements【发布时间】:2021-11-1414:34:15【问题描述】:如果我将dcc.Graph元素硬编码在布局中:app.layout=html.Div(html.Div([dcc.Graph(id=\'graph-hammer\'),dcc.Graph(id=\'graph-saw\'... 查看详情

Plotly Dash:选择 DataTable 中的行作为回调输出 + 过滤器

】PlotlyDash:选择DataTable中的行作为回调输出+过滤器【英文标题】:PlotlyDash:SelectRowsinDataTableasCallbackOutput+Filter【发布时间】:2020-09-1908:12:07【问题描述】:我有一个带有一些显示值的折线图的DataTable。我想实现它,以便单击图表... 查看详情

在 Plotly Dash 图表中放置刻度标签 - Python

】在PlotlyDash图表中放置刻度标签-Python【英文标题】:PlaceticklabelinsideinaPlotlyDashchart-Python【发布时间】:2021-10-2523:20:42【问题描述】:在我的PlotlyDash环境中,我遇到了在图表内放置分类刻度标签的问题。这是应用程序:importdashim... 查看详情

Plotly Dash 的卡片中未显示值

】PlotlyDash的卡片中未显示值【英文标题】:ValuenotshowninacardinPlotlyDash【发布时间】:2022-01-1616:51:51【问题描述】:我想在PlotlyDash的卡片中返回总销售额。我在返回值的回调中写的代码如下:@app.callback(Output(\'card_1\',\'children\'),Outp... 查看详情

如何为下拉菜单修复 plotly-dash 中的“回调错误”

】如何为下拉菜单修复plotly-dash中的“回调错误”【英文标题】:Howtofix\'CallbackError\'inplotly-dashforaDropdownMenu【发布时间】:2019-10-0612:30:49【问题描述】:我已尝试重新创建网络上显示的以下示例TowardsDataScienceExample我编写了以下代... 查看详情

Plotly Dash:如何在选项卡内显示三个相邻的图表

】PlotlyDash:如何在选项卡内显示三个相邻的图表【英文标题】:PlotlyDash:Howtodisplaythreegraphsnexttoeachotherinsideatab【发布时间】:2021-12-0920:19:19【问题描述】:我想显示三个并排的图表,每个都占据屏幕的三分之一。现在两个在一起... 查看详情

Choropleth Plotly Graph 未出现在 Dash 上

】ChoroplethPlotlyGraph未出现在Dash上【英文标题】:ChoroplethPlotlyGraphnotappearingonDash【发布时间】:2021-12-0115:26:01【问题描述】:我有一个包含各种状态的csv文件,以及它们在某些特定日期的分数。它在VSCodeNotebook中正确绘制,但是当... 查看详情