4  Visualisasi Data & Dashboard

Tujuan pembelajaran. Setelah menyelesaikan bab ini, kita akan mampu: 1. Memilih jenis chart yang tepat untuk setiap jenis pertanyaan analitis. 2. Menerapkan prinsip grammar of graphics dan data-ink ratio untuk menghasilkan visualisasi yang efektif. 3. Menggunakan matplotlib dan seaborn untuk visualisasi statis yang siap publikasi. 4. Menggunakan plotly untuk visualisasi interaktif yang dapat dieksplorasi. 5. Mengenali dan menghindari kesalahan visualisasi yang paling umum—terutama yang menyesatkan. 6. Merancang dashboard sederhana yang menjawab pertanyaan manajerial.

4.1 Mengapa Visualisasi?

Di Bab 3 kita menemukan bahwa churn rate pelanggan kontrak bulanan sekitar 43%, sementara kontrak dua tahun hanya sekitar 3%. Angka itu kuat. Tetapi ketika kita melihatnya dalam bentuk bar chart, kekuatannya berlipat: mata manusia langsung menangkap jarak antara dua batang, proporsi area, dan pola yang sulit diungkapkan dalam tabel.

Visualisasi adalah alat berpikir, bukan hanya alat presentasi. Sebagian besar analis menemukan insight bukan dari tabel yang mereka baca, melainkan dari grafik yang mereka lihat—karena otak manusia jauh lebih cepat memproses pola visual daripada angka.

Tip

Dua peran visualisasi. Pertama, exploratory: untuk diri kita sendiri, menemukan pola dan anomali. Kedua, explanatory: untuk audiens, menyampaikan insight yang sudah ditemukan. Keduanya membutuhkan pendekatan berbeda. Grafik eksplorasi boleh berantakan; grafik eksplanatori harus rapi dan terfokus. Bab ini mengajarkan keduanya.

4.2 Grammar of Graphics: Bahasa Universal Visualisasi

Sebelum menyentuh kode, pahami kerangka berpikir yang menjadi fondasi hampir semua library visualisasi modern (ggplot2, plotnine, plotly, altair): grammar of graphics (Wilkinson, 1999).

Setiap grafik dapat diuraikan menjadi komponen-komponen berikut:

Komponen Pertanyaan Contoh pada dataset kita
Data Data apa yang divisualisasikan? df dengan kolom Contract, tenure, Churn
Aesthetic (aes) Variabel mana yang dipetakan ke atribut visual? x = Contract, y = tenure, warna = Churn
Geometric (geom) Bentuk apa yang digunakan? Bar (geom_bar), titik (geom_point), garis (geom_line)
Facet Apakah data dibagi ke panel-panel? Panel per InternetService
Statistical transformation Apakah ada agregasi? Rata-rata per kategori, atau hitung (count)
Coordinate system Bagaimana posisi dipetakan ke bidang? Cartesian (default), polar (untuk pie chart)
Scale Bagaimana nilai dipetakan ke rentang visual? Log scale, warna kategori

Kerangka ini menjelaskan mengapa ggplot2 dan plotly terasa lebih konsisten dibandingkan matplotlib murni: keduanya mengekspresikan grafik sebagai kombinasi komponen, bukan sebagai instruksi imperatif (“gambar garis dari sini ke sini”).

Kita akan memakai matplotlib untuk kontrol penuh (statis) dan plotly untuk interaktivitas. seaborn menjembatani keduanya dengan API tingkat tinggi berbasis grammar of graphics.

4.3 Prinsip Tufte: Data-Ink Ratio

Edward Tufte, dalam bukunya The Visual Display of Quantitative Information, merumuskan prinsip yang menjadi standar emas visualisasi data:

“Above all else, show the data. Maximize the data-ink ratio, within reason.”

Data-ink adalah tinta (atau piksel) yang menampilkan data. Chartjunk adalah tinta yang tidak menampilkan data—garis grid berlebih, bayangan, gradien dekoratif, label sumbu yang berulang tanpa alasan.

Beberapa aturan praktis yang diturunkan dari prinsip ini:

Hindari Ganti dengan
Gridlines berlebih Gridlines minimal atau hilangkan
Border kotak penuh Garis sumbu ringan atau hilangkan
3D bar/pie chart 2D, tanpa dimensi palsu
Warna dekoratif Warna yang mengkodekan informasi
Label sumbu berulang Satu label sumbu yang jelas
Legend jika warna sudah jelas Direct labeling
Background berwarna Background putih atau abu-abu muda
Warning

Pie chart. Pie chart hampir selalu pilihan yang buruk untuk data analitis karena mata manusia buruk dalam membandingkan sudut dan area. Pie chart hanya masuk akal jika kita memiliki dua kategori dan ingin menyoroti bahwa satu mendominasi. Untuk semua kasus lain, bar chart lebih efektif—dan pada Bab 3 kita sudah memakai bar chart untuk Contract, bukan pie chart. Ini adalah pilihan yang disengaja.

4.4 Memilih Chart yang Tepat

Ini adalah tabel referensi yang perlu kita hafal (atau simpan sebagai cheat sheet):

Pertanyaan Chart yang tepat Contoh pada dataset kita
Bagaimana distribusi satu variabel kontinu? Histogram, density plot, boxplot Distribusi tenure
Bagaimana distribusi satu variabel kategorikal? Bar chart (count) Distribusi Contract
Bagaimana hubungan dua variabel kontinu? Scatter plot tenure vs MonthlyCharges
Bagaimana hubungan variabel kontinu dengan kategorikal? Boxplot, violin plot tenure per Contract
Bagaimana hubungan dua variabel kategorikal? Mosaic plot, stacked bar, heatmap Contract vs Churn
Bagaimana tren dari waktu ke waktu? Line chart (tidak berlaku untuk Telco)
Bagaimana korelasi antar banyak variabel? Correlation heatmap, scatter matrix Korelasi antar numerik (Bab 3)
Bagaimana komposisi (bagian dari keseluruhan)? Stacked bar, treemap Churn per Contract per InternetService
Bagaimana peringkat antar kategori? Horizontal bar (sorted) Churn rate per segmen
Tip

Aturan praktis pemula. Jika kita ragu antara pie chart dan bar chart, pilih bar chart. Jika ragu antara line chart dan bar chart, tanyakan apakah x-axis adalah waktu—jika ya, line; jika tidak, bar. Jika ragu antara dua grafik apa pun, pilih yang paling sederhana dan beri label yang jelas.

4.5 Visualisasi Statis: matplotlib dan seaborn

Kita sudah memakai keduanya di Bab 3. Di sini kita akan memperkenalkan pola yang konsisten agar grafik kita terlihat profesional tanpa perlu tweak berlebihan.

4.5.1 Setup Gaya Global

Code
import sys
sys.path.insert(0, ".")
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

from decanal.utils import load_churn_clean

# Gaya global untuk buku ini
sns.set_theme(style="whitegrid", palette="muted")
plt.rcParams["figure.dpi"] = 100
plt.rcParams["savefig.dpi"] = 150
plt.rcParams["font.size"] = 10

df = load_churn_clean()
Note

sn.set_theme(style="whitegrid") sudah menghapus sebagian besar chartjunk secara otomatis—gridlines ringan, latar belakang putih, dan font yang bersih. Ini adalah default yang wajar untuk sebagian besar kebutuhan. Jika kita membutuhkan kontrol lebih (misalnya untuk publikasi), gunakan style="ticks" dan hapus spines secara manual.

4.5.2 Histogram dan Density

Code
fig, ax = plt.subplots(figsize=(8, 3.5))
sns.histplot(data=df, x="tenure", kde=True, bins=30, color="#4C72B0", ax=ax)
ax.axvline(df["tenure"].median(), color="red", linestyle="--",
           label=f"Median = {df['tenure'].median():.0f} bulan")
ax.set_xlabel("Tenure (bulan)")
ax.set_ylabel("Jumlah pelanggan")
ax.set_title("Distribusi Tenure Pelanggan")
ax.legend()
plt.tight_layout()
plt.show()
Figure 4.1: Distribusi tenure dengan density overlay. Garis putus-putus menunjukkan median.

Perhatikan distribusi bimodal: puncak di sekitar awal (pelanggan baru) dan puncak di akhir (~70 bulan, pelanggan loyal). Ini tidak terlihat jelas di tabel statistik Bab 3—dan ini adalah alasan mengapa visualisasi melengkapi statistik deskriptif, bukan menggantikannya.

4.5.3 Bar Chart yang Diurutkan

Code
churn_rate = (df.groupby("Contract")["Churn"]
                .apply(lambda s: (s == "Yes").mean() * 100)
                .sort_values(ascending=True))

fig, ax = plt.subplots(figsize=(7, 3.5))
bars = ax.barh(churn_rate.index, churn_rate.values, color="#DD8452")
ax.bar_label(bars, fmt="%.1f%%", padding=3)
ax.set_xlabel("Churn rate (%)")
ax.set_ylabel("")
ax.set_title("Churn Rate per Tipe Kontrak")
ax.set_xlim(0, churn_rate.max() * 1.15)
plt.tight_layout()
plt.show()
Figure 4.2: Churn rate per tipe kontrak, diurutkan dari yang tertinggi.
Tip

Mengapa horizontal bar? Untuk kategori dengan label panjang, horizontal bar menghindari rotasi label yang sulit dibaca. Dan dengan mengurutkan dari nilai terkecil ke terbesar, mata langsung tertuju pada batang terpanjang di atas. Ini adalah pola standar untuk “peringkat” yang sebaiknya selalu kita gunakan.

4.5.4 Boxplot: Perbandingan Distribusi antar Kelompok

Code
fig, ax = plt.subplots(figsize=(8, 4))
sns.boxplot(data=df, x="Contract", y="tenure", hue="Churn",
            palette={"No": "#4C72B0", "Yes": "#DD8452"}, ax=ax)
ax.set_xlabel("Tipe kontrak")
ax.set_ylabel("Tenure (bulan)")
ax.set_title("Tenure per Kontrak dan Status Churn")
plt.tight_layout()
plt.show()
Figure 4.3: Distribusi tenure per tipe kontrak, dipisah berdasarkan status churn.

Boxplot menampilkan lima angka penting sekaligus: minimum, Q1, median, Q3, maksimum (di luar outlier). Ini adalah cara paling efisien untuk membandingkan distribusi antar kelompok—jauh lebih informatif daripada membandingkan rata-rata saja.

4.5.5 Small Multiples: Faceting

Ketika kita ingin membandingkan pola yang sama di banyak kelompok, facet (subplot per kelompok) jauh lebih efektif daripada menumpuk semua garis di satu grafik.

Code
g = sns.FacetGrid(df, col="Contract", hue="Churn", height=3, aspect=1.1,
                  palette={"No": "#4C72B0", "Yes": "#DD8452"})
g.map(sns.histplot, "tenure", bins=20, alpha=0.6)
g.add_legend(title="Churn")
g.set_axis_labels("Tenure (bulan)", "Jumlah")
g.figure.suptitle("Distribusi Tenure per Kontrak dan Churn", y=1.05)
plt.tight_layout()
plt.show()
Figure 4.4: Distribusi tenure per tipe kontrak, dipecah per status churn.

4.6 Visualisasi Interaktif: plotly

Grafik statis baik untuk laporan dan publikasi. Tetapi untuk eksplorasi dan dashboard, interaktivitas memberi nilai tambah besar: hover untuk detail, zoom untuk fokus, filter untuk segmen.

plotly adalah library visualisasi interaktif paling populer di Python, dan hasilnya dapat disematkan langsung di Quarto HTML.

4.6.1 Plotly Express: API Tingkat Tinggi

Code
import plotly.express as px

fig = px.scatter(
    df.sample(1000, random_state=42),  # sampel agar ringan
    x="tenure",
    y="MonthlyCharges",
    color="Churn",
    color_discrete_map={"No": "#4C72B0", "Yes": "#DD8452"},
    opacity=0.6,
    title="Tenure vs Monthly Charges (sampel 1.000 pelanggan)",
    labels={"tenure": "Tenure (bulan)", "MonthlyCharges": "Tagihan bulanan"},
)
fig.update_layout(width=750, height=420)
fig.show()
Figure 4.5: Hubungan tenure vs MonthlyCharges, diwarnai berdasarkan status churn. Arahkan kursor untuk detail.
Note

Mengapa sampel 1.000 baris? Plotly menyematkan data lengkap ke HTML, dan 7.043 titik scatter membuat file HTML besar dan browser lambat. Untuk eksplorasi, sampel representatif cukup. Untuk dashboard produksi, gunakan WebGL (render_mode="webgl") yang jauh lebih cepat untuk data besar, atau agregasi data sebelum divisualisasikan.

4.6.2 Bar Chart Interaktif dengan Grouping

Code
churn_seg = (df.groupby(["Contract", "InternetService"])["Churn"]
               .apply(lambda s: (s == "Yes").mean() * 100)
               .reset_index()
               .rename(columns={"Churn": "churn_rate"}))

fig = px.bar(
    churn_seg,
    x="Contract",
    y="churn_rate",
    color="InternetService",
    barmode="group",
    title="Churn Rate per Kontrak dan Layanan Internet",
    labels={"churn_rate": "Churn rate (%)", "Contract": "Tipe kontrak"},
    text_auto=".1f",
)
fig.update_layout(width=800, height=400, yaxis_range=[0, 70])
fig.show()
Figure 4.6: Churn rate per kombinasi kontrak dan layanan internet. Hover untuk detail.

Perhatikan pola: dalam setiap tipe layanan internet, churn rate pada kontrak bulanan jauh lebih tinggi daripada kontrak tahunan atau dua tahun. Ini menunjukkan bahwa efek kontrak lebih kuat daripada efek layanan internet—insight yang tidak langsung terlihat dari tabel tanpa memecah data dengan cara ini.

4.6.3 Tren dan Waktu (Pratinjau)

Karena Telco adalah data cross-sectional, tidak ada tren waktu. Namun untuk memberi kita gambaran, berikut contoh bagaimana tren waktu akan divisualisasikan menggunakan dataset pendamping (Retail Store Inventory). Blok ini tidak akan dijalankan di Bab 4—ini hanya pratinjau untuk Bab 10.

Code
# Pratinjau untuk Bab 10 — tidak dijalankan di sini
from decanal.utils import load_retail

retail = load_retail()
daily = retail.groupby("Date")["Units Sold"].sum().reset_index()

fig = px.line(daily, x="Date", y="Units Sold",
              title="Total Unit Terjual Harian (dataset retail)")
fig.show()
Figure 4.7

4.7 Kesalahan Visualisasi yang Harus Dihindari

Visualisasi yang buruk bukan hanya tidak informatif—ia bisa menyesatkan secara aktif. Berikut adalah kesalahan yang paling sering terjadi dan cara menghindarinya.

4.7.1 1. Sumbu Y yang Tidak Dimulai dari Nol

Code
data = {"Kuartal": ["Q1", "Q2", "Q3", "Q4"], "Pendapatan": [100, 103, 106, 108]}
d = pd.DataFrame(data)

fig, axes = plt.subplots(1, 2, figsize=(10, 3.5))
axes[0].bar(d["Kuartal"], d["Pendapatan"], color="#DD8452")
axes[0].set_ylim(98, 110)
axes[0].set_title("Sumbu dipotong (menyesatkan)")
axes[0].set_ylabel("Pendapatan (juta)")

axes[1].bar(d["Kuartal"], d["Pendapatan"], color="#4C72B0")
axes[1].set_ylim(0, 110)
axes[1].set_title("Sumbu dari nol (jujur)")
axes[1].set_ylabel("Pendapatan (juta)")
plt.tight_layout()
plt.show()
Figure 4.8: Efek sumbu Y yang dipotong. Grafik kiri menyesatkan; grafik kanan jujur.

Pada grafik kiri, pertumbuhan tampak dramatis—padahal dari Q1 ke Q4 hanya naik 8%. Memotong sumbu Y tidak selalu salah (kadang diperlukan untuk menonjolkan perbedaan kecil yang bermakna), tetapi harus disertai catatan eksplisit bahwa sumbu dipotong. Tanpa itu, ini adalah manipulasi visual.

4.7.2 2. Menggunakan Warna untuk Mengkodekan Terlalu Banyak Kategori

Mata manusia hanya bisa membedakan sekitar 7–8 warna dengan andal. Jika kategori kita lebih dari 7, gunakan strategi lain: facet, kelompokkan kategori kecil menjadi “other”, atau gunakan gradien (jika kategori berurutan).

Code
# Terlalu banyak kategori → sulit dibedakan
kategori = [f"Segmen {i}" for i in range(15)]
nilai = np.random.RandomState(42).randint(10, 100, 15)
fig, ax = plt.subplots(figsize=(8, 3.5))
ax.bar(kategori, nilai, color=plt.cm.tab20(np.linspace(0, 1, 15)))
ax.set_xticklabels(kategori, rotation=45, ha="right", fontsize=8)
ax.set_title("Kategori terlalu banyak — hindari ini")
plt.tight_layout()
plt.show()
Figure 4.9: Terlalu banyak warna sulit dibedakan. Pertimbangkan faceting untuk kategori > 7.

4.7.3 3. Dual Y-Axis

Grafik dengan dua sumbu Y (satu kiri, satu kanan) hampir selalu menyesatkan—karena korelasi visual bergantung sepenuhnya pada skala yang kita pilih. Korelasi yang tampak kuat dapat terlihat lemah hanya dengan mengubah skala sumbu kanan, dan sebaliknya. Gunakan facet atau dua grafik terpisah.

Warning

Aturan 3 dari 3. Tiga kesalahan yang harus selalu kita tanyakan sebelum mempublikasikan grafik: 1. Apakah sumbu Y dimulai dari nol (atau jujur jika tidak)? 2. Apakah ada lebih dari 7 warna kategori yang harus dibedakan? 3. Apakah ada dua sumbu Y?

Jika ada satu saja “ya” yang bermasalah, revisi.

4.8 Membangun Dashboard: Prinsip dan Praktik

Dashboard adalah kumpulan visualisasi yang dirancang untuk menjawab satu set pertanyaan secara bersamaan. Ia bukan sekadar “banyak grafik di satu halaman”—ia adalah produk dengan audiens, tujuan, dan hierarki informasi yang jelas.

4.8.1 Prinsip Dashboard yang Baik

Prinsip Penjelasan
Tujuan tunggal Satu dashboard = satu pertanyaan utama. Dashboard “semua tentang bisnis” tidak berguna.
Hierarki visual KPI utama paling besar dan paling atas; detail kecil di bawah.
Konsistensi warna Satu palet warna di seluruh dashboard, satu warna per kategori.
Konteks Setiap angka perlu pembanding—target, periode sebelumnya, rata-rata.
Ruang kosong Ruang kosong bukan pemborosan—ia memisahkan dan menekankan.

4.8.2 Contoh Dashboard Sederhana dengan Plotly

Berikut dashboard dua-panel yang menjawab satu pertanyaan manajerial: “Di mana churn paling terkonsentrasi, dan seberapa besar dampaknya?”

Code
from plotly.subplots import make_subplots
import plotly.graph_objects as go

# Data 1: Churn rate per kontrak
cr = (df.groupby("Contract")["Churn"]
        .apply(lambda s: (s == "Yes").mean() * 100)
        .sort_values())

# Data 2: Rata-rata tagihan bulanan per kontrak dan churn
charges = (df.groupby(["Contract", "Churn"])["MonthlyCharges"]
             .mean()
             .reset_index())

# Dashboard
fig = make_subplots(
    rows=1, cols=2,
    subplot_titles=("Churn rate per kontrak (%)",
                    "Rata-rata tagihan bulanan per kontrak"),
    column_widths=[0.5, 0.5],
)

fig.add_trace(
    go.Bar(x=cr.values, y=cr.index, orientation="h",
           marker_color="#DD8452", text=cr.round(1), textposition="outside",
           name="Churn rate"),
    row=1, col=1,
)

for status, color in [("No", "#4C72B0"), ("Yes", "#DD8452")]:
    subset = charges[charges["Churn"] == status]
    fig.add_trace(
        go.Bar(x=subset["Contract"], y=subset["MonthlyCharges"],
               name=f"Churn = {status}", marker_color=color),
        row=1, col=2,
    )

fig.update_layout(
    height=420, width=1000,
    title_text="Dashboard Churn — Telco Customer Churn",
    barmode="group",
    legend_title="Status",
    margin=dict(l=150, r=20, t=60, b=60),
)
fig.show()
Figure 4.10: Dashboard churn: (kiri) churn rate per kontrak; (kanan) rata-rata tagihan bulanan per kontrak dan status churn.
Note

Mengapa dashboard ini “benar”? Ia menjawab satu pertanyaan (di mana churn paling terkonsentrasi dan berapa harganya?), memiliki dua panel yang saling melengkapi (bukan dua grafik acak), menggunakan warna konsisten (oranye = churn, biru = non-churn), dan menyertakan label langsung (angka di batang) yang mengurangi kebutuhan akan legend dan sumbu terpisah.

4.8.3 Dashboard Interaktif dengan Widget

Untuk dashboard yang lebih lengkap, Plotly dapat dipadukan dengan ipywidgets (di Jupyter) atau disajikan sebagai aplikasi Dash (di luar cakupan buku ini). Untuk keperluan pengajaran, template di atas sudah memadai. Jika kita menginginkan dashboard yang dapat difilter, Quarto juga mendukung Observable JS untuk dashboard JavaScript-native.

4.9 Menyimpan Grafik untuk Buku

Ketika kita menyimpan grafik untuk Quarto book (HTML/PDF), ada beberapa pertimbangan:

Code
# Simpan grafik ke file (mis. untuk dipakai di luar Quarto)
fig_static, ax = plt.subplots(figsize=(8, 4))
sns.histplot(data=df, x="tenure", bins=30, ax=ax)
fig_static.savefig("images/tenure-distribution.png", dpi=150, bbox_inches="tight")

Untuk Quarto, tidak perlu menyimpan grafik ke file jika grafik dibuat di dalam chunk—Quarto akan menyematkannya langsung. Simpan ke file hanya jika kita ingin memakainya di slide atau bab lain.

4.10 Latihan Terbimbing

Latihan 4.1 — Chart selection. Untuk masing-masing pertanyaan berikut, pilih satu jenis chart yang paling tepat, dan jelaskan pilihan kita dalam satu kalimat: - (a) Bagaimana distribusi MonthlyCharges di antara pelanggan yang churn vs. bertahan? - (b) Berapa proporsi pelanggan yang churn di setiap kategori PaymentMethod? - (c) Apakah ada hubungan antara tenure dan MonthlyCharges? - (d) Bagaimana komposisi Churn di setiap InternetService?

Latihan 4.2 — Perbaiki grafik yang menyesatkan. Kode berikut membuat grafik yang menyesatkan. Perbaiki agar jujur secara visual:

fig, ax = plt.subplots()
ax.bar(["A", "B", "C"], [98, 99, 100])
ax.set_ylim(95, 101)

Jelaskan apa yang salah dan bagaimana kita memperbaikinya.

Latihan 4.3 — Dashboard satu pertanyaan. Buat dashboard dua-panel untuk menjawab pertanyaan: “Apakah pelanggan dengan lebih banyak layanan cenderung churn lebih jarang?” Gunakan kolom num_services yang dibuat di Bab 2. Dashboard harus memuat: (a) churn rate per num_services, dan (b) jumlah pelanggan per num_services (untuk memastikan churn rate tidak didasarkan pada sampel kecil).

Latihan 4.4 — Plotly interaktif. Buat scatter plot interaktif dengan Plotly yang menampilkan tenure vs TotalCharges, diwarnai berdasarkan Contract, dengan ukuran titik sebanding dengan MonthlyCharges. Tambahkan judul dan label sumbu yang jelas.

Latihan 4.5 — Refleksi kritis. Cari satu grafik di berita atau laporan perusahaan (atau dari internet) yang menurut kita menyesatkan. Identifikasi setidaknya satu prinsip visualisasi yang dilanggar dan jelaskan mengapa pelanggaran itu penting.

Petunjuk Latihan 4.2. Grafik tersebut memotong sumbu Y dari 95 hingga 101, membuat perbedaan 2% terlihat seperti perbedaan 100%. Perbaikan: (a) mulai sumbu Y dari 0, atau (b) jika memotong sumbu Y memang diperlukan untuk menonjolkan perbedaan kecil, beri anotasi eksplisit di grafik bahwa sumbu dipotong. Pilihan pertama lebih baik untuk audiens umum; pilihan kedua dapat diterima untuk audiens teknis yang memahami konteks.

4.11 Kotak “Jembatan”: Dari Data ke Keputusan

Important

Jembatan. Visualisasi mengubah cara keputusan dibuat:

  1. Mempercepat pemahaman. Di Bab 3, kita butuh tabel untuk melihat bahwa churn rate berbeda antar kontrak. Di Bab 4, satu bar chart menyampaikan insight yang sama dalam kurang dari 2 detik. Dalam rapat manajemen, kecepatan pemahaman adalah segalanya.

  2. Mengungkap pola tersembunyi. Distribusi tenure yang bimodal tidak terlihat dari statistik deskriptif—tetapi jelas dalam histogram. Pola ini memberi tahu kita bahwa ada dua populasi pelanggan dengan perilaku berbeda: pelanggan baru (rentan churn) dan pelanggan lama (loyal). Keputusan: strategi retensi untuk kedua populasi harus berbeda.

  3. Mengomunikasikan ketidakpastian. Grafik yang jujur—dengan sumbu Y dari nol, tanpa dual axis, dengan ukuran sampel yang ditampilkan—membangun kepercayaan. Grafik yang menyesatkan, bahkan jika tidak disengaja, merusak kredibilitas analisis.

  4. Memungkinkan eksplorasi mandiri. Dashboard interaktif memungkinkan pengambil keputusan mengeksplorasi data sendiri—mengubah filter, memperbesar segmen, memeriksa detail. Ini memberdayakan mereka untuk mengajukan pertanyaan yang tidak kita antisipasi, dan sering menghasilkan insight yang tidak kita temukan dalam analisis awal.

4.12 Rangkuman

Dalam bab ini kita telah:

  • Memahami grammar of graphics sebagai kerangka universal untuk berpikir tentang visualisasi: data, aesthetic, geometric, facet, transformation.
  • Menerapkan prinsip Tufte—data-ink ratio, penghindaran chartjunk—untuk menghasilkan grafik yang bersih dan efektif.
  • Memilih jenis chart yang tepat berdasarkan jenis pertanyaan analitis (distribusi, hubungan, tren, komposisi, peringkat).
  • Menguasai matplotlib dan seaborn untuk visualisasi statis siap publikasi: histogram, bar chart, boxplot, dan small multiples.
  • Menguasai plotly untuk visualisasi interaktif yang dapat disematkan langsung di Quarto HTML.
  • Mengenali dan menghindari kesalahan visualisasi yang paling umum: sumbu Y yang dipotong, terlalu banyak warna kategori, dual axis.
  • Merancang dashboard yang menjawab satu pertanyaan manajerial dengan hierarki visual dan konsistensi warna.
  • Mengintegrasikan visualisasi ke dalam alur keputusan, menyadari bahwa grafik yang baik mempercepat pemahaman dan membangun kepercayaan.

4.13 Jembatan ke Bab 5

Sampai di sini, kita telah mengukur (Bab 3) dan melihat (Bab 4). Tetapi kita belum benar-benar mendiagnosis—belum mengejar mengapa pola yang kita amati muncul. Bab berikutnya—Diagnostic Analytics—akan membawa kita lebih dalam:

  • Mengapa pelanggan kontrak bulanan lebih sering churn?
  • Apakah karena mereka lebih muda, atau lebih baru, atau karena alasan lain?
  • Bagaimana kita memisahkan efek dari sekadar korelasi?
  • Alat diagnostik apa yang dapat membantu kita menemukan akar masalah?

Bab 5 akan memperkenalkan teknik seperti analisis segmentasi, drill-down, analisis akar masalah, dan visual analytics untuk diagnosis—semuanya dibangun di atas fondasi statistik dan visualisasi dari dua bab sebelumnya.