EmpezarEmpieza gratis

Ampliar la cadena

¡Tu menú desplegable condicional fue todo un éxito! Limpió el panel y mejoró mucho la experiencia de usuario. Al presentar el producto, la persona interesada te pidió si podías implementar algunas mejoras.

Primero, quiere seleccionar un valor predeterminado para la categoría secundaria para que siempre aparezca algo en el gráfico. Tienes una idea de cómo hacerlo insertando un callback encadenado adicional entre los dos primeros que creaste.

Segundo, quiere mostrar un título bajo el gráfico que recuerde a los usuarios a qué categoría principal pertenece la categoría secundaria elegida. En lugar de otro callback, crees que se puede lograr enviando la categoría principal elegida a una salida adicional.

Este ejercicio forma parte del curso

Creación de paneles con Dash y Plotly

Ver curso

Instrucciones del ejercicio

  • Crea un callback debajo de la línea 37 que se dispare con el valor del desplegable major_cat_dd y tenga como salida tanto las options del desplegable minor_cat_dd como el elemento chosen_major_cat_title.
  • Crea otro callback debajo de la línea 52 que establezca un value predeterminado para el desplegable minor_cat_dd cuando se actualice su propiedad options.

ejercicio interactivo práctico

Prueba este ejercicio completando este código de ejemplo.

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)
Editar y ejecutar código