Nhấp để cập nhật biểu đồ khác
Biểu đồ cập nhật khi hover đã được đón nhận rất tốt. Thật kỳ diệu! Công việc của bạn đang biến những hình ảnh tĩnh mệt mỏi thành những trải nghiệm sống động.
Có một yêu cầu thay đổi bảng điều khiển bạn đã tạo ở bài trước. Cây báo cáo của công ty e-commerce bắt đầu từ quốc gia, rồi đến danh mục chính (major category), rồi danh mục phụ (minor category). Vì vậy, họ muốn việc hover không cập nhật biểu đồ cột bên dưới.
Thay vào đó, họ muốn khi bạn nhấp vào biểu đồ cột của danh mục chính thì biểu đồ cột phía dưới sẽ được cập nhật theo. Yêu cầu này nhằm giúp hiểu tỷ trọng doanh số theo danh mục chính khác nhau như thế nào giữa các quốc gia.
Dựa trên công việc gần đây về click và hover, bạn biết chính xác cách hiện thực điều này!
Bài tập này là một phần của khóa học
Xây dựng Dashboard với Dash và Plotly
Hướng dẫn bài tập
- Đảm bảo
'Major Category'có trong dữ liệu click bằng cách thêm nó vào tham sốcustom_datacủa biểu đồ cột danh mục chính bên dưới dòng37. - Thiết lập một callback bên dưới dòng
45để cập nhật biểu đồminor_catkhi một cột trong biểu đồmajor_catđược nhấp.
Bài tập tương tác thực hành trực tiếp
Hãy thử làm bài tập này bằng cách hoàn thành đoạn mã mẫu này.
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')
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 ($)'})
ecom_scatter = px.scatter(ecom_country, x='Total Sales ($)', y='Sales Volume', color='Country', width=350, height=550, custom_data=['Country'])
ecom_scatter.update_layout({'legend':dict(orientation='h', y=-0.7,x=1, yanchor='bottom', xanchor='right')})
app = Dash()
app.layout = [
html.Img(src=logo_link, style={'margin':'30px 0px 0px 0px'}),
html.H1('Sales breakdowns'),
html.Div([
html.H3('Sales Volume vs Sales Amount by Country'),
dcc.Graph(id='scatter', figure=ecom_scatter)],
style={'width':'350px', 'height':'650px', 'display':'inline-block',
'vertical-align':'top', 'border':'1px solid black', 'padding':'20px'}),
html.Div([
dcc.Graph(id='major_cat'),
dcc.Graph(id='minor_cat')],
style={'width':'700px', 'height':'650px','display':'inline-block'})
]
@callback(
Output('major_cat', 'figure'),
Input('scatter', 'hoverData'))
def update_major_cat_hover(hoverData):
hover_country = 'Australia'
if hoverData:
hover_country = hoverData['points'][0]['customdata'][0]
major_cat_df = ecom_sales[ecom_sales['Country'] == hover_country]
major_cat_agg = major_cat_df.groupby('Major Category')['OrderValue'].agg('sum').reset_index(name='Total Sales ($)')
ecom_bar_major_cat = px.bar(major_cat_agg, x='Total Sales ($)',
# Ensure the Major Category will be available
____=['Major Category'],
y='Major Category', height=300,
title=f'Sales by Major Category for: {hover_country}', color='Major Category',
color_discrete_map={'Clothes':'blue','Kitchen':'red', 'Garden':'green', 'Household':'yellow'})
ecom_bar_major_cat.update_layout({'margin':dict(l=10,r=15,t=40,b=0), 'title':{'x':0.5}})
return ecom_bar_major_cat
# Set up a callback for click data
@callback(
Output('minor_cat', 'figure'),
Input('____', '____'))
def update_major_cat_click(clickData):
click_cat = 'All'
major_cat_df = ecom_sales.copy()
total_sales = major_cat_df.groupby('Country')['OrderValue'].agg('sum').reset_index(name='Total Sales ($)')
if clickData:
click_cat = clickData['points'][0]['customdata'][0]
major_cat_df = ecom_sales[ecom_sales['Major Category'] == click_cat]
country_mj_cat_agg = major_cat_df.groupby('Country')['OrderValue'].agg('sum').reset_index(name='Total Sales ($)')
country_mj_cat_agg['Sales %'] = (country_mj_cat_agg['Total Sales ($)'] / total_sales['Total Sales ($)'] * 100).round(1)
ecom_bar_country_mj_cat = px.bar(country_mj_cat_agg, x='Sales %', y='Country',
orientation='h', height=450, range_x = [0,100], text='Sales %',
title=f'Global Sales % by Country for Major Category: {click_cat}')
ecom_bar_country_mj_cat.update_layout({'yaxis':{'dtick':1, 'categoryorder':'total ascending'}, 'title':{'x':0.5}})
return ecom_bar_country_mj_cat
if __name__ == '__main__':
app.run(debug=True)