Сюжетно-интерактивная столбчатая диаграмма с тире не возвращается

#python #pandas #plotly #plotly-dash

#python #панды #сюжетная #сюжетно-тире

Вопрос:

У меня есть следующий dataframe ( AllTransportModes_statistics_Tram ), который я хочу использовать для создания интерактивной столбчатой диаграммы (это ее пример):

       ContractName DepartureLineTransportMode  DayGroupNumber  Year  Month  
441   Lidingöbanan                       TRAM               1  2019      1   
442   Lidingöbanan                       TRAM               1  2019      2   
443   Lidingöbanan                       TRAM               1  2019      3   
444   Lidingöbanan                       TRAM               1  2019      4   
445   Lidingöbanan                       TRAM               1  2019      5   
1318     Tvärbanan                       TRAM               7  2020      5   
1319     Tvärbanan                       TRAM               7  2020      6   
1320     Tvärbanan                       TRAM               7  2020      7   
1321     Tvärbanan                       TRAM               7  2020      8   
1322     Tvärbanan                       TRAM               7  2020      9   

      count_nulls  count_rows  Percentage Null (%) (Imputated)  
441             0        3710                              0.0   
442             0        3400                              0.0   
443             0        3570                              0.0   
444             0        3400                              0.0   
445             0        3570                              0.0   
1318           77        2479                              3.1   
1319          240        2120                             11.3   
1320          431        1247                             34.6   
1321          454        1688                             26.9   
1322           75        1634                              4.6   

      Percentage Null (%) (Non-imputated) Origin  
441                                  37.2   Both  
442                                  24.5   Both  
443                                  22.9   Both  
444                                  23.2   Both  
445                                  20.1   Both  
1318                                 63.3   Both  
1319                                 67.0   Both  
1320                                 83.5   Both  
1321                                 78.7   Both  
1322                                 78.0   Both  
 

Теперь, что я хотел сделать, это иметь возможность выбрать три переменные ( ContractName , Year и DayGroupNumber ) из выпадающего списка и сгруппировать столбчатые диаграммы для переменных Percentage Null (%) (Non-imputated) и Percentage Null (%) (imputated) для каждого Month (т. Е. Каждая группа столбцов имеет свой месяц). Итак, для этого я написал следующий код:

 import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go

Avtal_options = AllTransportModes_statistics_Tram["ContractName"].unique()
Year_options   =AllTransportModes_statistics_Tram["Year"].unique()
Dagtyp_options   =AllTransportModes_statistics_Tram["DayGroupNumber"].unique()

app = dash.Dash()

app.layout = html.Div([
    html.H2("Missing data"),
    html.Div(
        [
            dcc.Dropdown(
                id="ContractName",
                options=[{
                    'label': i,
                    'value': i
                } for i in Avtal_options],
                value='All ContractName'),
            dcc.Dropdown(
                id="Year",
                options=[{
                    'label': i,
                    'value': i
                } for i in Year_options],
                value='All Years'),
            dcc.Dropdown(
                id="DayGroupNumber",
                options=[{
                    'label': i,
                    'value': i
                } for i in Dagtyp_options],
                value='All DayGroupNumbers'),
        ],
        style={'width': '25%',
               'display': 'inline-block'}),
    dcc.Graph(id='funnel-graph'),
])

@app.callback(
    dash.dependencies.Output('funnel-graph', 'figure'),
    [dash.dependencies.Input('ContractName','value'),
    dash.dependencies.Input('Year','value'),
    dash.dependencies.Input('DayGroupNumber','value')])
    
def update_graph(ContractName,Year,DayGroupNumber):
    if (ContractName == "All ContractName" amp; Year == "All Years" amp; DayGroupNumber == "All DayGroupNumbers"):
        AllTransportModes_statistics_Tram_plot = AllTransportModes_statistics_Tram.copy()
    else:
        AllTransportModes_statistics_Tram_plot = AllTransportModes_statistics_Tram[(AllTransportModes_statistics_Tram['ContractName'] == ContractName) amp; (AllTransportModes_statistics_Tram['Year'].astype(str)==Year) amp; (AllTransportModes_statistics_Tram['DayGroupNumber'].astype(str)==DayGroupNumber)]

   
    trace1 = go.Bar(x=AllTransportModes_statistics_Tram_plot['Month'],y=AllTransportModes_statistics_Tram_plot['Percentage Null (%) (Imputated)'], name='Percentage Null (%) (Imputated)')
    trace2 = go.Bar(x=AllTransportModes_statistics_Tram_plot['Month'], y=AllTransportModes_statistics_Tram_plot['Percentage Null (%) (Non-imputated)'], name='Percentage Null (%) (Non-imputated)')
    return {
        'data': [trace1, trace2],
        'layout':
        go.Layout(
            title='Jämförelse saknad data'.format(ContractName).format(DayGroupNumber).format(Year),
            barmode='stack')
    }


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

Как вы можете видеть, у меня есть опция, если выделение не выполнено (трассировки отображаются для всех ContractName s, Year s и DayGroupNumber s, в противном случае фильтруется исходный df

 if (ContractName == "All ContractName" amp; Year == "All Years" amp; DayGroupNumber == "All DayGroupNumbers"):
        AllTransportModes_statistics_Tram_plot = AllTransportModes_statistics_Tram.copy()
    else:
        AllTransportModes_statistics_Tram_plot = AllTransportModes_statistics_Tram[(AllTransportModes_statistics_Tram['ContractName'] == ContractName) amp; (AllTransportModes_statistics_Tram['Year'].astype(str)==Year) amp; (AllTransportModes_statistics_Tram['DayGroupNumber'].astype(str)==DayGroupNumber)]
 

Он НЕ отображает ничего, кроме этого

введите описание изображения здесь

Я просто не могу понять, что я делаю не так. Любая помощь будет оценена. Спасибо!

РЕДАКТИРОВАТЬ: обновить вопрос

Мне удалось частично решить вопрос. Что я теперь могу сделать, так это обновить график для функций Year и DayGroupNumber со следующими параметрами:

 def update_graph(ContractName,Year,DayGroupNumber):
    if ((ContractName == "All ContractNames") amp; (Year == "All Years") amp; (DayGroupNumber == "All DayGroupNumbers")):
        AllTransportModes_statistics_Tram_plot = AllTransportModes_statistics_Tram.copy()
    
    elif ((ContractName == "All ContractNames") amp; (Year == "All Years")):
        AllTransportModes_statistics_Tram_plot = AllTransportModes_statistics_Tram[(AllTransportModes_statistics_Tram['DayGroupNumber'].astype(str)==DayGroupNumber)]
        
    elif ((ContractName == "All ContractNames") amp; (DayGroupNumber == "All DayGroupNumbers")):
        AllTransportModes_statistics_Tram_plot = AllTransportModes_statistics_Tram[(AllTransportModes_statistics_Tram['Year'].astype(str)==Year)]
    
    elif ((ContractName == "All Years") amp; (DayGroupNumber == "All DayGroupNumbers")):
        AllTransportModes_statistics_Tram_plot = AllTransportModes_statistics_Tram[(AllTransportModes_statistics_Tram['ContractName']==ContractName)]
                             
    elif ((ContractName == "All ContractNames")):
        AllTransportModes_statistics_Tram_plot = AllTransportModes_statistics_Tram[(AllTransportModes_statistics_Tram['Year'].astype(str)==Year) amp; (AllTransportModes_statistics_Tram['DayGroupNumber'].astype(str)==DayGroupNumber)]
    
    elif ((ContractName == "All Years")):
        AllTransportModes_statistics_Tram_plot = AllTransportModes_statistics_Tram[(AllTransportModes_statistics_Tram['ContractName']==ContractName) amp; (AllTransportModes_statistics_Tram['DayGroupNumber'].astype(str)==DayGroupNumber)]
                                            
    elif ((ContractName == "All DayGroupNumbers")):
        AllTransportModes_statistics_Tram_plot = AllTransportModes_statistics_Tram[(AllTransportModes_statistics_Tram['ContractName']==ContractName) amp; (AllTransportModes_statistics_Tram['Year'].astype(str)==Year)]
    
    trace1 = go.Bar(x=AllTransportModes_statistics_Tram_plot['Month'], y=AllTransportModes_statistics_Tram_plot['Percentage Null (%) (Imputated)'], name='Percentage Null (%) (Imputated)')
    trace2 = go.Bar(x=AllTransportModes_statistics_Tram_plot['Month'], y=AllTransportModes_statistics_Tram_plot['Percentage Null (%) (Non-imputated)'], name='Percentage Null (%) (Non-imputated)')

    return {
        'data': [trace1, trace2],
        'layout':
        go.Layout(
            title='Jämförelse saknad data'.format(ContractName),
            barmode ='group')
    }

 

Однако выпадающий список для ContractName doe не работает, и, более того, если я попытаюсь применить его первым, то два других тоже не будут работать. Кроме того, ось y не соответствует масштабу.
введите описание изображения здесь

Ответ №1:

Решение этой проблемы состоит в том, чтобы охватить все возможные случаи фильтров в исходном фрейме данных, даже те, в которых выбор не был сделан. Вот полный код:

 import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go

Avtal_options = AllTransportModes_statistics_Tram["ContractName"].unique()
Year_options   =AllTransportModes_statistics_Tram["Year"].astype(str).unique()
Dagtyp_options   =AllTransportModes_statistics_Tram["DayGroupNumber"].astype(str).unique()

app = dash.Dash()

app.layout = html.Div([
    html.H2("Saknade data för spårbunden trafik"),
    html.Div(
        [
            dcc.Dropdown(
                id="ContractName",
                options=[{
                    'label': i,
                    'value': i
                } for i in Avtal_options],
                value='All ContractNames'
            ),
            dcc.Dropdown(
                id="Year",
                options=[{
                    'label': i,
                    'value': i
                } for i in Year_options],
                value='All Years'
             ),
            dcc.Dropdown(
                id="DayGroupNumber",
                options=[{
                    'label': i,
                    'value': i
                } for i in Dagtyp_options],
                value='All DayGroupNumbers',
            ),
        ],
        style={'width': '25%',
               'display': 'inline-block'}),
     dcc.Graph(id='funnel-graph'),
    ])



@app.callback(
    dash.dependencies.Output('funnel-graph', 'figure'),
    [dash.dependencies.Input('ContractName','value'),
    dash.dependencies.Input('Year','value'),
    dash.dependencies.Input('DayGroupNumber','value')])
    
def update_graph(ContractName,Year,DayGroupNumber):
    if ((ContractName == "All ContractNames") amp; (Year == "All Years") amp; (DayGroupNumber == "All DayGroupNumbers")):
        AllTransportModes_statistics_Tram_plot = AllTransportModes_statistics_Tram.copy()
    
    elif ((ContractName == "All ContractNames") amp; (Year == "All Years")):
        AllTransportModes_statistics_Tram_plot = AllTransportModes_statistics_Tram[(AllTransportModes_statistics_Tram['DayGroupNumber'].astype(str)==DayGroupNumber)]
        
    elif ((ContractName == "All ContractNames") amp; (DayGroupNumber == "All DayGroupNumbers")):
        AllTransportModes_statistics_Tram_plot = AllTransportModes_statistics_Tram[(AllTransportModes_statistics_Tram['Year'].astype(str)==Year)]
    
    elif ((Year == "All Years") amp; (DayGroupNumber == "All DayGroupNumbers")):
        AllTransportModes_statistics_Tram_plot = AllTransportModes_statistics_Tram[(AllTransportModes_statistics_Tram['ContractName']==ContractName)]
                             
    elif ((ContractName == "All ContractNames")):
        AllTransportModes_statistics_Tram_plot = AllTransportModes_statistics_Tram[(AllTransportModes_statistics_Tram['Year'].astype(str)==Year) amp; (AllTransportModes_statistics_Tram['DayGroupNumber'].astype(str)==DayGroupNumber)]
    
    elif ((Year == "All Years")):
        AllTransportModes_statistics_Tram_plot = AllTransportModes_statistics_Tram[(AllTransportModes_statistics_Tram['ContractName']==ContractName) amp; (AllTransportModes_statistics_Tram['DayGroupNumber'].astype(str)==DayGroupNumber)]
                                            
    elif ((DayGroupNumber == "All DayGroupNumbers")):
        AllTransportModes_statistics_Tram_plot = AllTransportModes_statistics_Tram[(AllTransportModes_statistics_Tram['ContractName']==ContractName) amp; (AllTransportModes_statistics_Tram['Year'].astype(str)==Year)]
    
    elif ((ContractName != "All ContractNames") amp; (Year != "All Years") amp; (DayGroupNumber != "All DayGroupNumbers")):
        AllTransportModes_statistics_Tram_plot = AllTransportModes_statistics_Tram[(AllTransportModes_statistics_Tram['ContractName']==ContractName) amp; (AllTransportModes_statistics_Tram['Year'].astype(str)==Year) amp; (AllTransportModes_statistics_Tram['DayGroupNumber'].astype(str)==DayGroupNumber)]
        
    trace1 = go.Bar(x=AllTransportModes_statistics_Tram_plot['Month'], y=AllTransportModes_statistics_Tram_plot['Percentage Null (%) (Imputated)'], name='Percentage Null (%) (Imputated)')
    trace2 = go.Bar(x=AllTransportModes_statistics_Tram_plot['Month'], y=AllTransportModes_statistics_Tram_plot['Percentage Null (%) (Non-imputated)'], name='Percentage Null (%) (Non-imputated)')

    return {
        'data': [trace1, trace2],
        'layout':
        go.Layout(
            title='Jämförelse saknad data'.format(ContractName),
            barmode ='group')
    }


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

которые возвращают правильные столбчатые диаграммы

введите описание изображения здесь