Estendere la catena
Il tuo menu a discesa condizionale è stato un successone! Ha ripulito la dashboard e migliorato di molto l'esperienza utente. Durante la demo del prodotto, la persona stakeholder ha chiesto se puoi implementare alcuni aggiornamenti.
Per prima cosa, desidera selezionare un valore predefinito per la categoria minore, così che il grafico mostri sempre qualcosa. Hai un'idea su come farlo inserendo un callback in catena aggiuntivo tra i primi due che hai creato.
Inoltre, vuole un titolo sotto il grafico che ricordi agli utenti a quale categoria maggiore appartiene la categoria minore scelta. Invece di un altro callback, pensi di poter ottenere questo risultato inviando la categoria maggiore selezionata a un output aggiuntivo.
Questo esercizio fa parte del corso
Creare dashboard con Dash e Plotly
Istruzioni dell'esercizio
- Crea un callback sotto la riga
37che venga attivato dal valore del menu a discesamajor_cat_dde che produca output sia per leoptionsdel menu a discesaminor_cat_ddsia per l'elementochosen_major_cat_title. - Crea un altro callback sotto la riga
52che imposti unvaluepredefinito per il menu a discesaminor_cat_ddquando si aggiorna la sua proprietàoptions.
esercizio interattivo pratico
Prova questo esercizio completando questo codice di esempio.
from dash import Dash, dcc, html, Input, Output, callback
import plotly.express as px
import pandas as pd
import random
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'}),
html.Div([
dcc.Graph(id='sales_line'),
html.H3(id='chosen_major_cat_title')],
style={'width':'700px', 'height':'650px','display':'inline-block'})
]
# Create a callback to set minor values and HTML output
@callback(
Output('____', '____'),
Output('____', 'children'),
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()
minor_options = [{'label':x, 'value':x} for x in relevant_minor_options]
if not major_cat_dd:
major_cat_dd = 'None Selected'
major_cat_title = f'This is in the Major Category of: {major_cat_dd}'
return minor_options, major_cat_title
# Create a callback to set a default minor category value
@callback(
Output('____', '____'),
Input('____', '____'))
def select_minor_cat(options):
chosen_val = 'None'
if options:
vals = [x['value'] for x in options]
chosen_val = random.choice(vals)
return chosen_val
@callback(
Output('sales_line', 'figure'),
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)