iBetter Books
수정

Matplotlib + Seaborn + Plotly 조합 전략

발표가 끝난 직후, 민서와 선배는 강의실 복도에서 잠깐 이야기를 나눴습니다. 교수님께서 시각화 자료가 특히 인상적이었다고 칭찬해주셨습니다.

"근데 선배, 발표 중에 '이 그래프를 마우스로 클릭할 수 있으면 좋겠다' 싶었어요. Seaborn은 정적이잖아요."

선배가 고개를 끄덕였습니다. "맞아. 그게 Seaborn의 한계이기도 해. 그래서 Plotly를 알아야 해."

세 도구의 포지셔닝

파이썬 시각화 생태계의 세 축을 이해하는 것이 중요합니다.

Matplotlib: 완전한 자유, 세밀한 제어

Matplotlib은 파이썬 시각화의 근간입니다. Seaborn과 Plotly 모두 내부적으로 Matplotlib 위에 올라가거나 영향을 받았습니다. 픽셀 하나까지 직접 제어할 수 있고, 논문이나 출판물처럼 정확한 레이아웃이 필요할 때 빛을 발합니다. 대신 기본 코드양이 많고, 통계 시각화를 만들 때는 직접 계산 로직을 추가해야 합니다.

Seaborn: 통계 시각화, 빠른 탐색

Seaborn은 "통계 시각화를 위한 Matplotlib 래퍼"입니다. barplot, boxplot, violinplot, heatmap 같은 통계 그래프를 단 몇 줄로 만들 수 있습니다. Pandas DataFrame과 자연스럽게 연동되고, 기본 스타일이 아름답습니다. 탐색적 데이터 분석(EDA) 단계에서 가장 생산적인 도구입니다. 단, 결과물은 정적 이미지입니다.

Plotly: 인터랙티브, 웹 대시보드

Plotly는 브라우저에서 동작하는 인터랙티브 차트를 만듭니다. 마우스 호버로 데이터 값 확인, 줌인/줌아웃, 특정 계열 숨기기 등이 가능합니다. Plotly Express를 사용하면 Seaborn처럼 간결한 코드로 인터랙티브 차트를 만들 수 있습니다. 웹 대시보드(Dash)와 결합하면 실시간 데이터 시각화 앱도 만들 수 있습니다.

상황별 선택 가이드

상황 추천 도구 이유
탐색적 데이터 분석(EDA) Seaborn 빠른 시각화, 통계 자동 계산
논문/학술 보고서 그래프 Matplotlib + Seaborn 세밀한 제어, 고해상도 출력
발표용 인터랙티브 차트 Plotly 청중이 직접 탐색 가능
웹 대시보드 Plotly + Dash 실시간 업데이트, 웹 배포
세밀한 커스터마이징 Matplotlib 완전한 자유도
빠른 프로토타입 Seaborn 또는 Plotly Express 코드량 최소화

Plotly Express 맛보기

Seaborn과 Plotly Express의 인터페이스는 놀랍도록 비슷합니다. 아래 코드를 실행하려면 pip install plotly로 Plotly를 먼저 설치해야 합니다.

import seaborn as snsimport plotly.express as pximport pandas as pdtips = sns.load_dataset("tips")# Seaborn 방식import matplotlib.pyplot as pltfig_sns, ax = plt.subplots(figsize=(8, 5))sns.scatterplot(data=tips, x="total_bill", y="tip", hue="sex", ax=ax)ax.set_title("Seaborn: 정적 차트")plt.tight_layout()plt.savefig("seaborn_scatter.png", dpi=100)plt.show()# Plotly Express 방식 (인터랙티브)fig_px = px.scatter(    tips,    x="total_bill",    y="tip",    color="sex",    title="Plotly: 인터랙티브 차트 (마우스 올려보기)",    labels={"total_bill": "Total Bill ($)", "tip": "Tip ($)"})fig_px.show()# fig_px.write_html("plotly_scatter.html")  # HTML로 저장 가능

실행 결과

두 코드의 구조가 거의 동일하다는 것을 알 수 있습니다. data=, x=, y=, color=(hue에 해당). Seaborn을 마스터했다면 Plotly Express로 넘어가는 데 하루면 충분합니다.

조합 예제: EDA → 최종 발표 워크플로우

실제 프로젝트에서는 세 도구를 단계별로 조합합니다.

import seaborn as snsimport matplotlib.pyplot as pltimport matplotlib.gridspec as gridspecimport pandas as pdimport numpy as np# ── 1단계: EDA는 Seaborn으로 빠르게 ──────────────────penguins = sns.load_dataset("penguins").dropna()print("=== EDA 단계: Seaborn으로 빠른 탐색 ===")# 변수 간 관계 파악g = sns.pairplot(penguins, hue="species", plot_kws={"alpha": 0.5})g.figure.suptitle("EDA: Pairplot (Seaborn)", y=1.02)plt.tight_layout()plt.show()# 분포 확인fig, axes = plt.subplots(1, 2, figsize=(12, 4))sns.histplot(data=penguins, x="flipper_length_mm",             hue="species", kde=True, ax=axes[0])axes[0].set_title("EDA: 날개 길이 분포")sns.boxplot(data=penguins, x="species", y="body_mass_g",            hue="species", ax=axes[1])axes[1].set_title("EDA: 체중 분포")plt.tight_layout()plt.show()# ── 2단계: 최종 발표 자료는 Matplotlib으로 다듬기 ────────print("\n=== 발표 자료: Matplotlib으로 정밀 조정 ===")# 논문/발표 스타일: 격자 없이, 선명하게plt.style.use("seaborn-v0_8-white")fig = plt.figure(figsize=(12, 8))gs = gridspec.GridSpec(2, 3, figure=fig, hspace=0.4, wspace=0.35)# 메인 차트: 산점도 (Seaborn으로 그리고 Matplotlib으로 다듬기)ax_main = fig.add_subplot(gs[0, :2])species_colors = {"Adelie": "#E74C3C", "Chinstrap": "#3498DB", "Gentoo": "#2ECC71"}for species, group in penguins.groupby("species"):    ax_main.scatter(        group["flipper_length_mm"],        group["body_mass_g"],        c=species_colors[species],        label=species,        alpha=0.7,        s=60,        edgecolors="white",        linewidths=0.5    )ax_main.set_xlabel("Flipper Length (mm)", fontsize=11)ax_main.set_ylabel("Body Mass (g)", fontsize=11)ax_main.set_title("Flipper Length vs. Body Mass by Species", fontsize=12, fontweight="bold")ax_main.legend(title="Species", frameon=True)ax_main.spines["top"].set_visible(False)ax_main.spines["right"].set_visible(False)# 우측 상단: 종별 비율 파이차트ax_pie = fig.add_subplot(gs[0, 2])species_counts = penguins["species"].value_counts()ax_pie.pie(    species_counts,    labels=species_counts.index,    colors=[species_colors[s] for s in species_counts.index],    autopct="%1.1f%%",    startangle=90,    pctdistance=0.85)ax_pie.set_title("Species Distribution", fontsize=10)# 하단 좌: 날개 길이 분포 (Seaborn 활용)ax_hist = fig.add_subplot(gs[1, 0])for species, group in penguins.groupby("species"):    ax_hist.hist(group["flipper_length_mm"], bins=15, alpha=0.6,                 color=species_colors[species], label=species, density=True)ax_hist.set_xlabel("Flipper Length (mm)", fontsize=10)ax_hist.set_ylabel("Density", fontsize=10)ax_hist.set_title("Flipper Length Distribution", fontsize=10)ax_hist.legend(fontsize=8)ax_hist.spines["top"].set_visible(False)ax_hist.spines["right"].set_visible(False)# 하단 중: 체중 분포 (Seaborn boxplot → Matplotlib 축에 삽입)ax_box = fig.add_subplot(gs[1, 1])sns.boxplot(data=penguins, x="species", y="body_mass_g",            palette=species_colors, hue="species",            legend=False, ax=ax_box, linewidth=1.5)ax_box.set_xlabel("Species", fontsize=10)ax_box.set_ylabel("Body Mass (g)", fontsize=10)ax_box.set_title("Body Mass by Species", fontsize=10)ax_box.spines["top"].set_visible(False)ax_box.spines["right"].set_visible(False)# 하단 우: 상관행렬 heatmapax_corr = fig.add_subplot(gs[1, 2])num_cols = ["bill_length_mm", "bill_depth_mm", "flipper_length_mm", "body_mass_g"]corr = penguins[num_cols].corr()sns.heatmap(corr, annot=True, fmt=".2f", cmap="coolwarm",            center=0, ax=ax_corr, cbar=False,            xticklabels=["Bill\nLen", "Bill\nDep", "Flipper", "Mass"],            yticklabels=["Bill\nLen", "Bill\nDep", "Flipper", "Mass"])ax_corr.set_title("Correlation", fontsize=10)fig.suptitle("Palmer Penguins: Comprehensive Analysis",             fontsize=14, fontweight="bold", y=1.01)plt.savefig("final_presentation.png", dpi=200, bbox_inches="tight",            facecolor="white")print("발표 자료 저장 완료: final_presentation.png")plt.show()

민서와 선배의 마무리 대화

대시보드를 완성하고 저장하는 동안 선배가 말했습니다.

"자, 이제 정리해볼게. EDA 할 때는 Seaborn. 빠르고, 통계를 자동으로 계산해주고, DataFrame과 잘 붙으니까. 최종 발표 자료나 논문 그림은 Matplotlib으로 다듬어. 픽셀 단위로 제어할 수 있거든. 그리고 청중이 직접 탐색하게 하고 싶거나 웹에 올려야 하면 Plotly."

민서가 고개를 끄덕이며 물었습니다. "세 가지를 다 배워야 하는 거네요. 힘들지 않나요?"

"사실 핵심 개념은 같아. x, y, hue, 제목, 레이블. 하나를 잘 배우면 나머지는 금방이야. 너 지금 Seaborn을 제대로 배웠으니까, Matplotlib이랑 Plotly는 이제 2~3일이면 쓸 수 있어."

"그럼 저 이제 세 가지 도구를 상황에 맞게 골라 쓸 줄 알게 된 건가요?"

선배가 웃으며 답했습니다. "정확해. 그게 진짜 실력이야."

세 도구를 함께 배우기 위한 로드맵

지금까지 이 교재를 통해 Seaborn을 익혔습니다. 다음 단계로 나아가고 싶다면 아래 순서를 추천합니다.

  1. Matplotlib 심화: Artist 객체, GridSpec, FuncAnimation. 논문 수준의 그래프 제어.
  2. Plotly Express: px.scatter, px.bar, px.line. Seaborn과 인터페이스가 비슷해서 빠르게 익힐 수 있습니다.
  3. Plotly Graph Objects: 더 세밀한 인터랙티브 제어가 필요할 때.
  4. Dash: Plotly 기반 웹 대시보드 프레임워크. 실시간 데이터 시각화 앱 개발.

핵심 정리

  • Matplotlib은 완전한 자유도와 세밀한 제어, Seaborn은 통계 시각화와 빠른 탐색, Plotly는 인터랙티브와 웹 대시보드에 강점이 있습니다.
  • 실전에서는 "EDA → Seaborn, 최종 발표 → Matplotlib 다듬기, 인터랙티브 → Plotly"의 워크플로우를 따릅니다.
  • Seaborn을 마스터했다면 Plotly Express로의 전환은 하루면 충분합니다.
  • 도구를 많이 아는 것보다 상황에 맞는 도구를 고를 줄 아는 것이 더 중요합니다.