호버로 다른 플롯 업데이트하기
글로벌 e-commerce 회사는 당신의 작업이 오래된 보고서에 불어넣은 혁신과 새 생명에 크게 만족하고 있어요. 최근에 핵심 지표를 호버로 보여주는 대시보드를 만들어 준 그 매니저가 새로운 과제를 보냈습니다. 단어로 요약하는 것도 좋지만, 한 장의 그림이 천 마디 말을 대신하죠! 매니저는 호버한 대상에 따라 서로 다른 하위 집합을 보여주는 그래프를 만들 수 있는지 요청했어요.
이전에 콜백을 사용해 데이터를 필터링하고 figure를 다시 생성했던 경험과, 최근에 호버로 콜백을 트리거하는 작업을 결합하면 이 과제에 딱 맞는 해법이 될 거예요.
이 연습은 강의의 일부입니다
Dash와 Plotly로 대시보드 만들기
연습 안내
- 26번째 줄 아래에 있는
scatter플롯에 마우스를 올렸을 때minor_cat그래프를 업데이트하는 콜백을 만드세요. - 41번째 줄 아래에 있는
scatter플롯에 마우스를 올렸을 때major_cat그래프를 업데이트하는 콜백을 만드세요.
실습형 인터랙티브 연습
이 예제를 이 샘플 코드를 완성하여 풀어보세요.
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'})
]
# Create a callback to update the minor category plot
@callback(
Output('____', '____'),
Input('scatter', '____'))
def update_min_cat_hover(hoverData):
hover_country = 'Australia'
if hoverData:
hover_country = hoverData['points'][0]['customdata'][0]
minor_cat_df = ecom_sales[ecom_sales['Country'] == hover_country]
minor_cat_agg = minor_cat_df.groupby('Minor Category')['OrderValue'].agg('sum').reset_index(name='Total Sales ($)')
ecom_bar_minor_cat = px.bar(minor_cat_agg, x='Total Sales ($)', y='Minor Category', orientation='h', height=450, title=f'Sales by Minor Category for: {hover_country}')
ecom_bar_minor_cat.update_layout({'yaxis':{'dtick':1, 'categoryorder':'total ascending'}, 'title':{'x':0.5}})
return ecom_bar_minor_cat
# Create a callback to update the major category plot
@callback(
Output('____', '____'),
Input('scatter', '____'))
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 ($)',
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
if __name__ == '__main__':
app.run(debug=True)