Как реализовать выпадающее меню в Plotly Dash с использованием Python?

#python #pandas #plotly #plotly-dash

#питон #сюжетно #сюжетно-тире

Вопрос:

В этом приложении я пытаюсь отобразить график, который изменяется при изменении значения в выпадающем меню. Ценности — это районы Лондона. С данными можно ознакомиться здесь. Ниже приведен код для базового графика.

 import plotly.graph_objects as go

df = pd.read_excel('multi-year-station-entry-and-exit-figures.xls', sheet_name='2017 Entry amp; Exit', skiprows=6)

df = df.loc[df['Borough'] == 'Islington']

df['Sunday'] = df['Sunday']   df['Sunday.1']
df['Saturday'] = df['Saturday']   df['Saturday.1']

df = df[['Borough', 'Station', 'Saturday', 'Sunday']]
df.index = range(len(df))
print(df['Borough'])

fig = go.Figure(data=[
    go.Bar(name='Saturday', x=df["Station"], y=df["Saturday"]),
    go.Bar(name='Sunday', x=df["Station"], y=df["Sunday"])
])

fig.update_layout(title='Weekend entry and exit figures in 2017',
                  xaxis_tickfont_size=14,
                  yaxis=dict(
                      title='Entry and exit numbers',
                      titlefont_size=16,
                      tickfont_size=14,
                  )
                  , barmode='group', template='plotly_dark', bargap=0.3, bargroupgap=0.1)
fig.show()
 

Я могу изменить название района вручную, чтобы изменить сюжет. Затем я создал приложение Dash с помощью выпадающего меню. Однако я не могу понять, как изменить график при выборе выпадающего списка. Я создал версию с использованием условных операторов, в которой я добавляю оператор if-elif для каждого района. Однако я все еще не могу изменить сам сюжет. По сути, мне нужно включить этот фрагмент кода df = df.loc[df['Borough'] == 'Islington'] в приложение Dash. Код приложения Dash показан ниже.

 import dash_core_components as dcc
import dash_html_components as html
import plotly.express as px
import pandas as pd
import os
import plotly.io as pio
import plotly.graph_objects as go
import dash_bootstrap_components as dbc

df = pd.read_excel('multi-year-station-entry-and-exit-figures.xls', sheet_name='2017 Entry amp; Exit', skiprows=6)

df['Sunday'] = df['Sunday']   df['Sunday.1']
df['Saturday'] = df['Saturday']   df['Saturday.1']

df = df[['Borough', 'Station', 'Saturday', 'Sunday']]
df.index = range(len(df))
df = df[:-3]

app = dash.Dash()

fig_names = ['Islington', 'Camden']
fig_dropdown = html.Div([
    dcc.Dropdown(
        id='fig_dropdown',
        options=[{'label': x, 'value': x} for x in fig_names],
        value=None
    )])
fig_plot = html.Div(id='fig_plot')
app.layout = html.Div([fig_dropdown, fig_plot])


@app.callback(
    dash.dependencies.Output('fig_plot', 'children'),
    [dash.dependencies.Input('fig_dropdown', 'value')])
def update_output(fig_name):
    return name_to_figure(fig_name)


def name_to_figure(fig_name):
    figure = go.Figure()
    if fig_name == 'Islington':
        figure = go.Figure(data=[
            go.Bar(name='Saturday', x=df["Station"], y=df["Saturday"]),
            go.Bar(name='Sunday', x=df["Station"], y=df["Sunday"])
        ])
    elif fig_name == 'Camden':
        figure = go.Figure(data=[
            go.Bar(name='Saturday', x=df["Station"], y=df["Saturday"]),
            go.Bar(name='Sunday', x=df["Station"], y=df["Sunday"])
        ])
    return dcc.Graph(figure=figure)


app.run_server(debug=True, use_reloader=False)
 

Ответ №1:

Вы можете создать копию своего фрейма данных, содержащую только данные, соответствующие выпадающему выбору, а затем использовать этот отфильтрованный фрейм данных для генерации фигуры:

 import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objects as go

app = dash.Dash()

# load the data
df = pd.read_excel('multi-year-station-entry-and-exit-figures.xls', sheet_name='2017 Entry amp; Exit', skiprows=6)
df['Sunday'] = df['Sunday']   df['Sunday.1']
df['Saturday'] = df['Saturday']   df['Saturday.1']
df = df[['Borough', 'Station', 'Saturday', 'Sunday']]
df.index = range(len(df))
df = df[:-3]

# extract the list of all boroughs
fig_names = df['Borough'].unique().tolist()

# generate the app layout
app.layout = html.Div([

    # add a dropdown for selecting the borough
    html.Div([
        dcc.Dropdown(
            id='fig_dropdown',
            options=[{'label': x, 'value': x} for x in fig_names],
            value=fig_names[0]  # use the first borough as the initial selection
        )]),

    # add a container for the figure
    html.Div(id='fig_plot'),

])

# define a callback for updating the figure
# based on the dropdown selection
@app.callback(dash.dependencies.Output('fig_plot', 'children'),
             [dash.dependencies.Input('fig_dropdown', 'value')])
def update_output(fig_name):

    # extract the data for the selected borough
    df_fig = df[df['Borough'] == fig_name]

    # plot the data for the selected borough
    figure = go.Figure(data=[
        go.Bar(name='Saturday', x=df_fig['Station'], y=df_fig['Saturday']),
        go.Bar(name='Sunday', x=df_fig['Station'], y=df_fig['Sunday'])
    ])

    return dcc.Graph(figure=figure)

if __name__ == '__main__':
    app.run_server(debug=True, host='0.0.0.0', port=1234)