条件付きドロップダウンオプション
あるeコマース企業の上級購買担当者から興味深い課題が出されました。アイテムのマイナーカテゴリごとの月次売上を表示する既存のダッシュボードでは、2段階のドロップダウン(メジャーカテゴリとマイナーカテゴリ)に選択肢が多すぎます。特に困るのは、2つ目のドロップダウンに選べない選択肢が表示されることだそうです。
あなたは支援できると伝えます——これは、連鎖コールバックを使って条件付きドロップダウンを実装する絶好の機会です。
この演習はコースの一部です
Dash と Plotly で作るダッシュボード
演習の手順
- 行
31の下にコールバックを作成し、major_cat_ddドロップダウンの値に基づいてminor_cat_ddドロップダウンのoptionsを更新します。 - 行
39の下にあるrelevant_minor_options変数を、labelとvalueキーが同一の辞書リストに整形し直します。 - 行
43の下にもう一つコールバックを作成し、minor_cat_ddドロップダウンの値に基づいてsales_lineグラフのfigureを更新します。
実践的なインタラクティブ演習
このサンプルコードを完成させて、この演習に挑戦してみましょう。
from dash import Dash, dcc, html, Input, Output, callback
import plotly.express as px
import pandas as pd
ecom_sales = pd.read_csv('/usr/local/share/datasets/ecom_sales.csv')
major_categories = list(ecom_sales['Major Category'].unique())
minor_categories = list(ecom_sales['Minor Category'].unique())
logo_link = 'https://assets.datacamp.com/production/repositories/5893/datasets/fdbe0accd2581a0c505dab4b29ebb66cf72a1803/e-comlogo.png'
ecom_country = ecom_sales.groupby('Country')['OrderValue'].agg(['sum', 'count']).reset_index().rename(columns={'count':'Sales Volume', 'sum':'Total Sales ($)'})
app = Dash()
app.layout = [
html.Img(src=logo_link, style={'margin':'30px 0px 0px 0px'}),
html.H1('Sales breakdowns'),
html.Div([
html.H2('Controls'),
html.Br(),
html.H3('Major Category Select'),
dcc.Dropdown(
id='major_cat_dd',
options=[{'label':category, 'value':category} for category in major_categories],
style={'width':'200px', 'margin':'0 auto'}),
html.Br(),
html.H3('Minor Category Select'),
dcc.Dropdown(id='minor_cat_dd', style={'width':'200px', 'margin':'0 auto'})],
style={'width':'350px', 'height':'350px', 'display':'inline-block',
'vertical-align':'top', 'border':'1px solid black', 'padding':'20px'}),
dcc.Graph(id='sales_line',style={'width':'700px', 'height':'650px','display':'inline-block'})
]
# Create a callback from the Major Category dropdown to the Minor Category Dropdown
@callback(
Output('____', '____'),
Input('major_cat_dd', 'value'))
def update_minor_dd(major_cat_dd):
major_minor = ecom_sales[['Major Category', 'Minor Category']].drop_duplicates()
relevant_minor_options = major_minor[major_minor['Major Category'] == major_cat_dd]['Minor Category'].values.tolist()
# Set up the Major Category options with the same label and value
formatted_relevant_minor_options = [{'label':____, 'value':____} for ____ in ____]
return formatted_relevant_minor_options
# Create a callback for the Minor Category dropdown to update the line plot
@callback(
Output('____', '____'),
Input('minor_cat_dd', 'value'))
def update_line(minor_cat):
minor_cat_title = 'All'
ecom_line = ecom_sales.copy()
if minor_cat:
minor_cat_title = minor_cat
ecom_line = ecom_line[ecom_line['Minor Category'] == minor_cat]
ecom_line = ecom_line.groupby('Year-Month')['OrderValue'].agg('sum').reset_index(name='Total Sales ($)')
line_graph = px.line(ecom_line, x='Year-Month', y='Total Sales ($)', title=f'Total Sales by Month for Minor Category: {minor_cat_title}')
return line_graph
if __name__ == '__main__':
app.run(debug=True)