Get startedGet started for free

Analyzing top customer locations

From your good work with the e-commerce company, you have been asked to help them build on an existing report looking at their sales by country.

The sales manager is interested in understanding where their top customers are located. They don't currently have a clear idea of what 'top' means. Ideally, they can easily try a variety of different cut-off values to consider someone a top customer and see how the graph changes with different cut-off values.

Your task is to help the sales manager by using a range input to facilitate a live-update app that filters sales by a minimum OrderValue amount.

This exercise is part of the course

Building Dashboards with Dash and Plotly

View Course

Exercise instructions

  • Create an input that the user can slide to select a value between 50 and 550 below line 46.
  • Ensure the callback is triggered whenever the slider stops moving below line 49.
  • In the triggered callback, check if an input has been entered below line 78 and, if so, use the input to filter for sales with an OrderValue strictly greater than the input.
  • In the plot, insert the user input value into the title, so users know what has been selected below line 85.

Hands-on interactive exercise

Have a go at this exercise by completing this sample code.

import dash
from dash import dcc, html
import plotly.express as px
import pandas as pd
from dash.dependencies import Input, Output
from datetime import datetime, date
ecom_sales = pd.read_csv('/usr/local/share/datasets/ecom_sales.csv')
logo_link = 'https://assets.datacamp.com/production/repositories/5893/datasets/fdbe0accd2581a0c505dab4b29ebb66cf72a1803/e-comlogo.png'

def make_break(num_breaks):
    br_list = [html.Br()] * num_breaks
    return br_list

def add_logo():
    corp_logo = html.Img(
        src=logo_link, 
        style={'margin':'20px 20px 5px 5px',
              'border':'1px dashed lightblue',
              'display':'inline-block'})
    return corp_logo

def style_c():
    layout_style={
        'display':'inline-block',
        'margin':'0 auto',
        'padding':'20px',
    }
    return layout_style

app = dash.Dash(__name__)

app.layout = html.Div([
  add_logo(),
  *make_break(2),
  html.H1('Sales Dashboard'),
  *make_break(3),
  html.Div(
    children=[
    html.Div(
        children=[
        html.H2('Controls', style=style_c()),
        html.H3('Set minimum OrderValue'),
        *make_break(2),
        dcc.Input(
          # Create the specified input
          id='min_order_val', type='____', 
          ____=____, ____=550, value=50,
          # Ensure the callback is triggered only when the user stops moving the slider
          ____=False,
        style={'width':'300px', 'height':'30px'})
        ],
        style={'width':'350px', 'height':'350px', 'vertical-align':'top', 'border':'1px solid black',
        'display':'inline-block', 'margin':'0px 80px'}),
    html.Div(children=[
            dcc.Graph(id='sales_country'),
            html.H2('Sales Quantity by Country', 
            style={ 'border':'2px solid black', 'width':'400px', 'margin':'0 auto'})
            ],
             style={'width':'700px','display':'inline-block'}
             ),
    ])
    ], 
  style={'text-align':'center', 'display':'inline-block', 'width':'100%'}
  )

@app.callback(
    Output(component_id='sales_country', component_property='figure'), 
    Input(component_id='min_order_val', component_property='value'))

def update_plot(input_val):
  
    if not input_val:
      input_val = 0
  
    sales = ecom_sales.copy(deep=True)

    # Check for input then use to subset data
    ____:
        input_val = round(float(input_val), 2)
        sales = sales[sales['OrderValue'] > ____]
    
    fig = px.scatter(data_frame=sales, y='OrderValue', height=400,
                     x='Quantity', color='Country',
					 # Set the conditional title
                     title=f'Orders of Min Value ${____}')
    return fig
      
if __name__ == '__main__':
    app.run_server(debug=True)
Edit and Run Code