首页 > 解决方案 > 如何使用 Python 在 Plotly Dash 中实现下拉菜单?

问题描述

我对 Plotly Dash 相当陌生,我正在尝试创建一个简单的 Dash 应用程序。在这个应用程序中,我试图显示一个在下拉菜单中的值更改时更改的图。这些值是伦敦的行政区。下面是基本图的代码。

import plotly.graph_objects as go

df = pd.read_excel('multi-year-station-entry-and-exit-figures.xls', sheet_name='2017 Entry & 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 应用程序。However, I can't figure out how to change the plot when a dropdown option is selected. 我使用条件语句创建了一个版本,其中我为每个行政区添加了一个 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 & 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)

数据可以在这里找到。这是我第一次使用 Stack Overflow,所以请忽略任何格式问题。在此先感谢您的帮助

标签: pythonpandasplotlyplotly-dash

解决方案


您可以创建仅包含与下拉选择对应的数据的数据框副本,然后使用此过滤后的数据框生成图形:

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

推荐阅读