2 분 소요

Plotly 인터랙티브 요소: 버튼과 드롭다운으로 대시보드 만들기

데이터 시각화의 꽃은 뭐니 뭐니 해도 사용자가 직접 데이터를 탐색할 수 있는 인터랙티브(Interactive) 요소라고 생각한다. 오늘은 Kaggle World Happiness Report 데이터를 활용해서, Plotly의 updatemenus 기능으로 버튼과 드롭다운을 구현하고 이를 세밀하게 튜닝하는 방법을 정리해 봤다.


1. 데이터 준비 및 설정

먼저 데이터를 불러오고 분석할 지표들을 정의한다.

import pandas as pd
import plotly.graph_objects as go

# 데이터 로드
df = pd.read_csv('world_happiness_report.csv')

# 1. 설정: 분석할 연도와 지표 정의
years = sorted(df['Year'].unique(), reverse=True)[:5]  # 최근 5개년
metrics = {
    'Happiness_Score': '행복 점수',
    'Healthy_Life_Expectancy': '기대 수명',
    'Social_Support': '사회적 지지'
}
metric_keys = list(metrics.keys())

2. 초기 그래프 생성

드롭다운을 만들기 전에, 가장 기본이 되는 첫 화면 그래프를 그려야 한다. 초기 연도와 초기 지표를 선택해서 산점도(Scatter Plot)를 그린다.

initial_year = years[0]
initial_metric = metric_keys[0]
curr_df = df[df['Year'] == initial_year]

fig = go.Figure()

fig.add_trace(
    go.Scatter(
        x=curr_df['GDP_per_Capita'],
        y=curr_df[initial_metric],
        mode='markers',
        text=curr_df['Country'],
        marker=dict(
            size=14,
            color=curr_df[initial_metric],
            colorscale='Electric',
            showscale=True,
            line=dict(width=1, color='White')
        ),
        name=metrics[initial_metric]
    )
)

3. 드롭다운(Dropdown) 구현: 연도 선택

updatemenus의 핵심은 method="update"다. 버튼을 클릭했을 때 데이터(x, y, text)를 새 데이터로 갈아끼우는 방식이다.

year_options = []
for year in years:
    year_df = df[df['Year'] == year]
    year_options.append(
        dict(
            method="update",
            label=f"{year}년",  # 라벨에 이모지 추가로 직관성 UP
            args=[{
                "x": [year_df['GDP_per_Capita']],
                "y": [year_df[initial_metric]],
                "text": [year_df['Country']]
            }]
        )
    )

4. 버튼(Button) 구현: 지표 전환

이번엔 탭(Tab) 메뉴처럼 생긴 버튼을 만들어보자. 여기서는 단순히 데이터만 바꾸는 게 아니라, 축 제목차트 제목까지 동적으로 변경해야 한다. args의 두 번째 인자로 레이아웃 업데이트 정보를 넘겨주면 된다.

metric_buttons = []
for key, name in metrics.items():
    metric_buttons.append(
        dict(
            method="update",
            label=name,
            args=[
                {"y": [curr_df[key]], "marker.color": [curr_df[key]]},  # 데이터 변경
                {"yaxis": {"title": name}, "title": f"<b>GDP 대비 {name} 상관관계</b>"}  # 레이아웃 변경
            ]
        )
    )

5. 레이아웃 튜닝 (UI/UX 최적화)

이제 만든 메뉴들을 적절한 위치에 배치해야 한다.

fig.update_layout(
    template="plotly_dark",
    title=dict(text=f"<b>GDP 대비 {metrics[initial_metric]} 상관관계</b>", x=0.5, font=dict(size=20)),
    xaxis_title="1인당 GDP (Purchasing Power)",
    yaxis_title=metrics[initial_metric],
    margin=dict(t=120),  # 상단 여백 확보 (메뉴 공간)

    updatemenus=[
        # 1. 드롭다운 배치 (상단 왼쪽)
        dict(
            type="dropdown",
            buttons=year_options,
            direction="down",
            showactive=True,
            x=0.0, xanchor="left", y=1.2, yanchor="top"
        ),
        # 2. 버튼 배치 (상단 오른쪽)
        dict(
            type="buttons",
            buttons=metric_buttons,
            direction="right",
            x=1.0, xanchor="right", y=1.2, yanchor="top",
            bgcolor="rgba(255, 255, 255, 0.1)",  # 투명도 있는 배경
            font=dict(color="white")
        ),
    ]
)

fig.show()
  • margin: 메뉴가 차트 제목을 가리지 않도록 상단 여백(t=120)을 넉넉히 준다.
  • xanchor, yanchor: 드롭다운은 왼쪽 끝, 버튼은 오른쪽 끝에 배치하여 균형을 맞췄다.

6. 정리

Plotly의 updatemenus는 자바스크립트를 몰라도 파이썬만으로 훌륭한 인터랙티브 대시보드를 만들 수 있게 해준다.

기능 속성/값 설명
메뉴 타입 type="dropdown" / "buttons" 드롭다운 메뉴 또는 버튼 그룹 선택
동작 방식 method="update" 데이터와 레이아웃을 동시에 변경
데이터 변경 args=[{data_dict}, ...] 첫 번째 인자로 트레이스 데이터 변경 (x, y, marker.color 등)
레이아웃 변경 args=[..., {layout_dict}] 두 번째 인자로 레이아웃 속성 변경 (title, yaxis 등)
배치 x, y, xanchor, yanchor 메뉴의 위치 지정 (0~1 좌표계)

단순히 정적인 그래프를 보여주는 것보다, 사용자가 직접 연도를 바꾸고 지표를 바꿔가며 데이터를 탐색하게 하면 분석의 깊이가 달라진다. 다음에는 슬라이더(Slider)를 연동해서 시계열 변화를 애니메이션으로 보여주는 것도 시도해봐야겠다.


Reference

댓글남기기