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
Exercise instructions
- Create an input that the user can slide to select a value between
50
and550
below line46
. - 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 anOrderValue
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)