Mengubah data menjadi cerita visual: Matplotlib untuk kontrol penuh, Seaborn untuk statistik & distribusi, dan Plotly untuk interaktivitas — plus prinsip storytelling visual dan praktik membuat dashboard insight

Setelah di episode 6 kita menemukan insight lewat EDA, pada episode ini kita belajar menyajikannya: data visualization. Grafik adalah bahasa yang paling cepat dipahami manusia — dan bagi data scientist, kemampuan visual sering menjadi pembeda antara insight yang dibaca orang dan insight yang diabaikan.
Mengapa visualisasi penting? Karena angka tidak bercerita sendiri. churn 18% adalah angka abstrak; tapi line chart yang menunjukkan churn melonjak setiap kali harga naik adalah cerita yang membuat stakeholder bertindak. Visualisasi yang baik juga sering mengungkap pola yang luput dari statistik — nonlinearitas, segmen aneh, atau data yang salah.
| Library | Kekuatan | Cocok untuk |
|---|---|---|
| Matplotlib | Kontrol penuh, ringan | Grafik dasar & kustomisasi mendalam |
| Seaborn | Statistik, rapi, perawatan rendah | Distribusi, korelasi, perbandingan grup |
| Plotly | Interaktif, hover, zoom | Dashboard & eksplorasi web |
Mulai dari Matplotlib + Seaborn untuk notebook; gunakan Plotly saat audience butuh interaktivitas (misal dashboard eksekutif).
Semua dimulai dari pyplot. Pola dasarnya: siapkan figure → plot → sesuaikan label → tampilkan.
import matplotlib.pyplot as plt
months = ["Jan", "Feb", "Mar", "Apr", "Mei", "Jun"]
churn = [0.18, 0.19, 0.17, 0.21, 0.24, 0.23]
plt.figure(figsize=(8, 4))
plt.plot(months, churn, marker="o")
plt.title("Churn Rate per Bulan")
plt.ylabel("Churn Rate")
plt.grid(alpha=0.3)
plt.show()Aturan kecil yang berdampak besar: selalu beri judul, label sumbu, dan unit. Grafik tanpa label adalah pesan yang hilang.
Seaborn membuat plot statistik yang "standar data science" jadi satu baris:
import seaborn as sns
import pandas as pd
df = pd.read_csv("telco_churn.csv")
sns.kdeplot(data=df, x="monthly_charges", hue="churn", fill=True)
sns.boxplot(data=df, x="churn", y="tenure")
sns.heatmap(df.select_dtypes("number").corr(), cmap="coolwarm",
annot=False, square=True)Tiga plot ini menjawab tiga pertanyaan EDA: apakah distribusi berbeda antar grup? apakah median berbeda? apakah ada korelasi antar fitur? — masing-masing dalam satu baris kode.
sns.pairplot(df, vars=["tenure", "monthly_charges", "total_charges"],
hue="churn", diag_kind="kde")Untuk dataset kecil, pairplot memberi peta hubungan dua-dua variabel sekaligus. Untuk dataset besar, plot ini terlalu mahal — cukup tampilkan subset kolom.
Visualisasi yang efektif mengikuti prinsip berikut:
import matplotlib.pyplot as plt
import numpy as np
months = list(range(1, 13))
revenue = [10, 11, 10.5, 12, 13, 12.5, 14, 15, 14.5, 16, 17, 16.5]
plt.figure(figsize=(9, 4))
plt.plot(months, revenue, color="tab:gray", label="2025")
plt.plot(months, [r * 1.12 for r in revenue], color="tab:blue", label="2026")
plt.axhline(y=18, color="red", linestyle="--", linewidth=1)
plt.text(1, 18.2, "Target 2026", color="red", fontsize=9)
plt.legend()
plt.title("Pendapatan Bulanan: 2025 vs 2026")
plt.ylabel("Juta Rp")
plt.grid(alpha=0.3)
plt.show()Perhatikan: hanya dua series + satu garis target. Informasi fokus, tidak berisik, dan pesannya jelas.
Tip
Aturan praktis "satu grafik satu pesan" juga berlaku untuk slide. Jika sebuah grafik membutuhkan paragraf penjelasan, berarti grafiknya belum cukup baik — ubah grafiknya, bukan perpanjang penjelasannya.
Untuk dashboard dan eksplorasi web, Plotly memberi hover, zoom, dan filter bawaan:
import plotly.express as px
fig = px.scatter(
df, x="tenure", y="monthly_charges", color="churn",
size="total_charges", hover_data=["contract"],
title="Tenure vs Monthly Charges (warna: churn)",
)
fig.show()Plotly juga menyatu dengan panel dashboard (Dash) dan bisa diekspor ke HTML untuk dibagikan tanpa server.
Gabungkan semuanya menjadi dashboard insight churn yang siap dipresentasikan:
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
df = pd.read_csv("telco_churn.csv")
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
fig.suptitle("Churn Dashboard - Telco", fontsize=14)
sns.boxplot(data=df, x="churn", y="tenure", ax=axes[0, 0])
sns.kdeplot(data=df, x="monthly_charges", hue="churn",
fill=True, ax=axes[0, 1])
churn_rate = df.groupby("contract")["churn"].mean()
churn_rate.plot.bar(ax=axes[1, 0], color=["#7fd1a5", "#ffb347", "#ff6b6b"])
df.groupby("churn")["total_charges"].mean().plot.bar(ax=axes[1, 1])
plt.tight_layout()
plt.show()Empat panel ini sudah menceritakan keseluruhan cerita churn: pelanggan baru (tenure rendah), tarif tinggi, kontrak bulanan, dan tagihan besar. Dashboard adalah versi rapi dari cerita yang sama.
| Pitfall | Dampak | Solusi |
|---|---|---|
| Grafik tanpa label & unit | Pesan hilang | Selalu judul + label sumbu |
| Pie chart berlebihan | Sulit dibandingkan | Bar chart / sorted bar |
| Sumbu dipotong menyesatkan | Persepsi salah | Jaga proporsi jujur |
| Terlalu banyak warna/legenda | Berisik, tidak fokus | Satu warna untuk pesan utama |
| Melupakan konteks | Angka tanpa makna | Tambahkan baseline & target |
Inti yang harus dibawa pulang:
Di episode 8 selanjutnya kita akan membahas SQL untuk data science — menarik dan memanipulasi data langsung dari database dengan query, aggregation, dan feature extraction. Sampai jumpa di episode 8!