MA1420 · DATA SAINS · SESI 03

Statistik Deskriptif II:
Visualisasi & Distribusi Data

Satu grafik bisa menggantikan ribuan angka. Di sesi ini kita belajar memilih jenis visualisasi yang tepat, membaca bentuk distribusi data, dan memahami skewness & kurtosis — kemampuan yang wajib dimiliki setiap data scientist.

1. Visualisasi sebagai Alat Komunikasi Data

Bayangkan Anda punya tabel 1.000 baris angka. Berapa lama waktu yang dibutuhkan untuk memahaminya? Dengan grafik yang tepat, pemahaman bisa dicapai dalam kurang dari 5 detik.

💡 ILUSTRASI — PETA vs DAFTAR ALAMAT

Mana lebih mudah dipahami: daftar 500 koordinat GPS di spreadsheet, atau peta dengan titik-titik berwarna yang menunjukkan lokasi tersebut?

Itulah fungsi visualisasi data — mengubah angka abstrak menjadi gambar yang langsung "masuk" ke otak. Otak manusia memproses gambar 60.000 kali lebih cepat dari teks. Visualisasi yang baik = komunikasi data yang efektif.

🎯 TUJUAN VISUALISASI DATA

Eksplorasi: Menemukan pola, tren, dan anomali yang tersembunyi

Komunikasi: Menyampaikan temuan kepada orang lain secara jelas

Konfirmasi: Memverifikasi asumsi atau hipotesis secara visual

Pengambilan Keputusan: Menjadi dasar rekomendasi yang bisa dipercaya

2. Jenis-Jenis Visualisasi dan Kapan Menggunakannya

Tidak semua grafik cocok untuk semua situasi. Memilih grafik yang salah sama seperti menggunakan kompas untuk mengukur suhu — alatnya ada, tapi tidak tepat sasaran.

📊
Histogram
Menampilkan distribusi frekuensi satu variabel numerik kontinu
📌 Kapan: Lihat sebaran nilai ujian, penghasilan, tinggi badan
📈
Bar Chart
Membandingkan nilai antar kategori atau kelompok
📌 Kapan: Bandingkan penjualan per kota, jumlah mahasiswa per prodi
🥧
Pie Chart
Menampilkan proporsi/persentase dari keseluruhan
📌 Kapan: Porsi pasar (maks 5 kategori), komposisi anggaran
📦
Boxplot
Ringkasan distribusi: median, Q1, Q3, outlier dalam satu gambar
📌 Kapan: Bandingkan distribusi antar kelompok, deteksi outlier
🔵
Scatter Plot
Melihat hubungan/korelasi antara dua variabel numerik
📌 Kapan: Nilai UTS vs UAS, tinggi vs berat badan
📉
Line Chart
Menampilkan tren atau perubahan data sepanjang waktu
📌 Kapan: Harga saham harian, suhu mingguan, penjualan bulanan
💡 PANDUAN MEMILIH CHART — ANALOGI ALAT DAPUR

Histogram = timbangan (mengukur sebaran berat/nilai satu bahan)
Bar Chart = penggaris (membandingkan panjang/besar beberapa bahan)
Pie Chart = pisau untuk memotong kue (lihat proporsi setiap potongan)
Scatter Plot = tali jemuran (lihat apakah dua hal "bergerak bersamaan")
Line Chart = kalender (lacak perubahan dari waktu ke waktu)
Boxplot = kotak obat (rangkum semua informasi penting dalam satu kotak)

Contoh Visual: Histogram Nilai Ujian

HISTOGRAM · DISTRIBUSI NILAI UAS MAHASISWA (n=30)
2
4
6
9
12
9
6
3
1
50-54
55-59
60-64
65-69
70-74
75-79
80-84
85-89
90-94

↑ Distribusi ini mendekati simetris (lonceng) — puncak di tengah, menurun ke kanan-kiri. Ini mendekati distribusi normal.

3. Identifikasi Bentuk Distribusi

Dari histogram, kita bisa "membaca" karakter data. Ada tiga bentuk utama yang perlu dikenali — seperti mengenali wajah seseorang dari foto.

⚖️ Simetris (Normal)
Mean ≈ Median ≈ Modus. Bentuk lonceng (bell curve). Data tersebar merata di kiri-kanan.
Contoh: tinggi badan, nilai IQ, error pengukuran
➡️ Skewed Right (+)
Ekor panjang ke kanan. Mean > Median > Modus. Kebanyakan nilai kecil, sedikit yang sangat besar.
Contoh: gaji, harga rumah, kekayaan, pendapatan perusahaan
⬅️ Skewed Left (−)
Ekor panjang ke kiri. Mean < Median < Modus. Kebanyakan nilai besar, sedikit yang sangat kecil.
Contoh: nilai ujian mudah, usia pensiun, masa pakai barang lama
💡 ILUSTRASI — DISTRIBUSI GAJI DI INDONESIA

Gaji di Indonesia adalah contoh klasik skewed right (positif): sebagian besar pekerja bergaji Rp 3–8 juta/bulan (nilai kecil, banyak), tapi ada segelintir CEO dan pejabat bergaji ratusan juta (nilai besar, sedikit). Ekornya panjang ke kanan.

Itulah mengapa BPS selalu menggunakan median pendapatan, bukan mean, agar tidak "menyesatkan" dengan rata-rata yang ditarik oleh kelompok super-kaya.

4. Skewness dan Kurtosis

4.1 Skewness (Kemiringan)

Skewness mengukur seberapa miring distribusi data. Nilainya bisa positif, negatif, atau nol.

FORMULA SKEWNESS (PEARSON) Skewness = Σ[(xᵢ − x̄)³] / [(n−1) × s³] s = standar deviasi; nilai positif = miring kanan; negatif = miring kiri; mendekati 0 = simetris
≈ 0
Simetris
Distribusi seimbang. Mean ≈ Median. Contoh: nilai ujian seimbang.
+ (Positif)
Skewed Right
Ekor ke kanan. Mean > Median. Banyak data kecil, sedikit sangat besar.
− (Negatif)
Skewed Left
Ekor ke kiri. Mean < Median. Banyak data besar, sedikit sangat kecil.

4.2 Kurtosis (Keruncingan)

Kurtosis mengukur seberapa runcing atau datar puncak distribusi — apakah data "berkumpul" tajam di tengah atau tersebar lebih merata.

TipeNilai KurtosisBentuk PuncakContoh
Leptokurtic Kurtosis > 3 (excess > 0) Sangat runcing, ekor tebal — banyak outlier Harga saham harian (sering ada lonjakan ekstrem)
Mesokurtic Kurtosis = 3 (excess = 0) Puncak sedang — distribusi normal Tinggi badan, IQ, error pengukuran normal
Platykurtic Kurtosis < 3 (excess < 0) Datar, ekor tipis — data tersebar merata Lemparan dadu (distribusi uniform)
⚡ ATURAN PRAKTIS INTERPRETASI SKEWNESS

• |skewness| < 0.5 → distribusi mendekati simetris, aman pakai mean

• 0.5 ≤ |skewness| < 1.0 → distribusi miring sedang, pertimbangkan transformasi log

• |skewness| ≥ 1.0 → distribusi sangat miring, sebaiknya pakai median & transformasi data

5. Distribusi Normal dan Pengecekan Normalitas

Distribusi Normal (Gaussian) adalah distribusi terpenting dalam statistika. Banyak metode analisis statistik mengasumsikan data berdistribusi normal.

💡 ILUSTRASI — KURVA LONCENG DAN ATURAN 68-95-99.7

Bayangkan seorang guru menilai 10.000 lembar ujian. Jika sebaran nilainya normal, maka: 68% siswa nilainya dalam jarak ±1 SD dari mean, 95% siswa dalam ±2 SD, dan 99.7% siswa dalam ±3 SD. Hanya 0.3% yang sangat jauh dari rata-rata — inilah outlier sejati.

📐 ATURAN 68-95-99.7 (EMPIRICAL RULE)

Untuk data normal dengan mean (μ) dan standar deviasi (σ):

• μ ± 1σ → mencakup ~68% data

• μ ± 2σ → mencakup ~95% data

• μ ± 3σ → mencakup ~99.7% data

Contoh: IQ rata-rata 100, SD=15. Maka 95% orang punya IQ antara 70-130.

Cara Mengecek Normalitas

💡 ILUSTRASI — Q-Q PLOT SEPERTI CERMIN

Q-Q plot membandingkan distribusi data Anda dengan distribusi normal teoritis. Bayangkan berdiri di depan cermin: jika bayangan Anda identik dengan yang di cermin (titik mengikuti garis lurus) → data Anda normal. Jika bayangan "melengkung" atau "berputar" → data tidak normal.

6. Prinsip Visualisasi yang Baik dan Efektif

PRINSIP 01
Pilih Chart yang Tepat
Sesuaikan jenis grafik dengan tujuan dan tipe data yang ingin divisualisasikan.
✗ Pie chart untuk 15 kategori
✓ Bar chart untuk banyak kategori
PRINSIP 02
Beri Judul & Label Jelas
Setiap grafik harus bisa dipahami sendiri tanpa penjelasan tambahan.
✗ Sumbu tanpa label satuan
✓ "Nilai Ujian (0-100)" di sumbu y
PRINSIP 03
Mulai Sumbu Y dari Nol
Memulai dari angka tengah dapat membuat perbedaan kecil tampak dramatis.
✗ Sumbu y mulai dari 95 (distorsi visual)
✓ Mulai dari 0 untuk bar chart
PRINSIP 04
Hindari Dekorasi Berlebihan
Efek 3D, gradien, dan animasi bisa mengalihkan dari pesan utama.
✗ Pie chart 3D yang susah dibaca
✓ Grafik sederhana dan bersih
PRINSIP 05
Gunakan Warna Bermakna
Warna harus memperjelas, bukan sekadar dekorasi. Konsisten dalam satu presentasi.
✗ Tiap bar warna berbeda tanpa makna
✓ Merah = negatif, hijau = positif
PRINSIP 06
Satu Grafik, Satu Pesan
Jangan memaksakan terlalu banyak informasi dalam satu grafik. Pecah jika perlu.
✗ 10 variabel dalam satu line chart
✓ Pisah menjadi beberapa grafik kecil

7. Praktik: Visualisasi dengan Matplotlib & Seaborn

7.1 Setup dan Dataset

PYTHON · SETUP VISUALISASI
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats

# Atur gaya visualisasi agar lebih cantik
sns.set_theme(style="darkgrid", palette="muted")
plt.rcParams['figure.figsize'] = (10, 6)

# Dataset: nilai mahasiswa dari 3 kelas berbeda
np.random.seed(42)
kelas_a = np.random.normal(loc=75, scale=8, size=50)   # distribusi normal
kelas_b = np.random.exponential(scale=15, size=50) + 50 # skewed right
kelas_c = 100 - np.random.exponential(scale=10, size=50)  # skewed left

df = pd.DataFrame({
    'Nilai': np.concatenate([kelas_a, kelas_b, kelas_c]),
    'Kelas': ['A']*50 + ['B']*50 + ['C']*50
})
df['Nilai'] = df['Nilai'].clip(0, 100)  # batasi 0-100

7.2 Histogram — Lihat Distribusi

PYTHON · HISTOGRAM
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
judul = ['Kelas A (Normal/Simetris)', 
         'Kelas B (Skewed Right +)', 
         'Kelas C (Skewed Left −)']
data_list = [kelas_a, kelas_b, kelas_c]
warna = ['#3B82F6', '#F59E0B', '#8B5CF6']

for i, (ax, data, title, color) in enumerate(zip(axes, data_list, judul, warna)):
    ax.hist(data, bins=15, color=color, alpha=0.8, edgecolor='white')
    ax.axvline(np.mean(data), color='red', linestyle='--', label=f'Mean={np.mean(data):.1f}')
    ax.axvline(np.median(data), color='green', linestyle='-', label=f'Median={np.median(data):.1f}')
    ax.set_title(title, fontsize=11)
    ax.set_xlabel('Nilai')
    ax.set_ylabel('Frekuensi')
    ax.legend(fontsize=9)
    
    # Hitung dan tampilkan skewness
    skew = stats.skew(data)
    ax.text(0.05, 0.95, f'Skewness: {skew:.2f}',
           transform=ax.transAxes, verticalalignment='top',
           bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5))

plt.tight_layout()
plt.savefig('histogram_distribusi.png', dpi=150)
plt.show()
💡 HASIL YANG DIHARAPKAN

• Kelas A: histogram berbentuk lonceng simetris, Mean ≈ Median, skewness ≈ 0

• Kelas B: histogram ekor panjang ke kanan, Mean > Median, skewness > 0 (positif)

• Kelas C: histogram ekor panjang ke kiri, Mean < Median, skewness < 0 (negatif)

7.3 Boxplot — Ringkasan + Deteksi Outlier

PYTHON · BOXPLOT PERBANDINGAN KELAS
plt.figure(figsize=(10, 6))

# Boxplot dengan Seaborn (lebih cantik)
sns.boxplot(data=df, x='Kelas', y='Nilai', 
            palette=['#3B82F6', '#F59E0B', '#8B5CF6'],
            width=0.5)

# Tambahkan titik data asli (strip plot)
sns.stripplot(data=df, x='Kelas', y='Nilai', 
             color='white', alpha=0.4, size=4, jitter=True)

plt.title('Boxplot Perbandingan Nilai Tiga Kelas', fontsize=14)
plt.xlabel('Kelas')
plt.ylabel('Nilai Ujian')

# Tambahkan anotasi penjelasan boxplot
plt.annotate('● = Outlier', xy=(0.02, 0.98), xycoords='axes fraction',
             va='top', fontsize=9, color='gray')

plt.tight_layout()
plt.show()
📦 CARA MEMBACA BOXPLOT

Garis tengah kotak = Median (Q2)

Batas bawah kotak = Q1 (25%)

Batas atas kotak = Q3 (75%)

Panjang kotak = IQR (Q3 − Q1)

Kumis/whisker = rentang normal (Q1−1.5×IQR sampai Q3+1.5×IQR)

Titik di luar kumis = outlier

7.4 Q-Q Plot — Cek Normalitas

PYTHON · Q-Q PLOT DAN UJI NORMALITAS
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
kelas_names = ['Kelas A', 'Kelas B', 'Kelas C']

for ax, data, name in zip(axes, data_list, kelas_names):
    # Buat Q-Q plot
    (osm, osr), (slope, intercept, r) = stats.probplot(data, dist="norm")
    ax.scatter(osm, osr, alpha=0.7, color='#3B82F6', s=30)
    ax.plot(osm, slope * np.array(osm) + intercept, 'r-', linewidth=2)
    
    ax.set_title(f'Q-Q Plot {name}')
    ax.set_xlabel('Kuantil Teoritis (Normal)')
    ax.set_ylabel('Kuantil Data')
    
    # Uji Shapiro-Wilk (formal)
    stat_sw, p_sw = stats.shapiro(data)
    status = "NORMAL" if p_sw > 0.05 else "TIDAK NORMAL"
    ax.text(0.05, 0.95, f'Shapiro p={p_sw:.3f}\n{status}',
           transform=ax.transAxes, va='top', fontsize=9,
           bbox=dict(boxstyle='round', facecolor='#1e3a5f'))

plt.tight_layout()
plt.show()
📤 OUTPUT YANG DIHARAPKAN
Kelas A → Q-Q plot titik mengikuti garis lurus  → Shapiro p > 0.05 → NORMAL ✓
Kelas B → Q-Q plot melengkung ke atas           → Shapiro p < 0.05 → TIDAK NORMAL ✗  
Kelas C → Q-Q plot melengkung ke bawah          → Shapiro p < 0.05 → TIDAK NORMAL ✗

7.5 Scatter Plot — Hubungan Dua Variabel

PYTHON · SCATTER PLOT UTS vs UAS
# Buat data nilai UTS dan UAS yang berkorelasi
np.random.seed(10)
uts = np.random.normal(75, 10, 60)
uas = uts + np.random.normal(0, 8, 60)   # UAS ≈ UTS + noise
uts = np.clip(uts, 40, 100)
uas = np.clip(uas, 40, 100)

plt.figure(figsize=(8, 6))
plt.scatter(uts, uas, alpha=0.7, color='#3B82F6', s=60, edgecolors='white', linewidth=0.5)

# Tambahkan garis tren (regresi linear)
z = np.polyfit(uts, uas, 1)
p = np.poly1d(z)
x_line = np.linspace(uts.min(), uts.max(), 100)
plt.plot(x_line, p(x_line), 'r--', linewidth=2, label='Garis Tren')

plt.title('Scatter Plot: Nilai UTS vs UAS')
plt.xlabel('Nilai UTS')
plt.ylabel('Nilai UAS')
plt.legend()

# Korelasi Pearson
r, p_val = stats.pearsonr(uts, uas)
plt.annotate(f'r = {r:.2f} (korelasi positif kuat)', 
             xy=(0.05, 0.92), xycoords='axes fraction', fontsize=10)

plt.tight_layout()
plt.show()

Uji Pemahaman Sesi 3

🧩 PERTANYAAN 1 — PILIHAN CHART
Anda ingin melihat apakah ada hubungan antara jam belajar dan nilai ujian mahasiswa. Chart apa yang PALING TEPAT?
Benar! Scatter plot adalah pilihan tepat untuk melihat hubungan antara dua variabel numerik (jam belajar vs nilai). Setiap titik mewakili satu mahasiswa dengan koordinat (jam_belajar, nilai_ujian).
🧩 PERTANYAAN 2 — SKEWNESS
Data gaji karyawan menghasilkan histogram dengan ekor panjang ke kanan dan skewness = +1.8. Apa yang bisa disimpulkan?
Benar! Skewness +1.8 (positif, >1) berarti distribusi sangat miring ke kanan (right-skewed). Mean ditarik ke kanan oleh gaji-gaji besar, sehingga Mean > Median. Mayoritas karyawan bergaji relatif kecil, hanya segelintir yang bergaji sangat besar.
🧩 PERTANYAAN 3 — Q-Q PLOT
Pada Q-Q plot, titik-titik data membentuk kurva melengkung ke atas (bukan mengikuti garis lurus). Apa interpretasinya?
Benar! Q-Q plot yang titiknya mengikuti garis lurus = distribusi normal. Jika melengkung (ke atas atau bawah), berarti data menyimpang dari normalitas. Melengkung ke atas = right-skewed. Ini penting karena banyak uji statistik mengasumsikan data normal.
📋 Ringkasan Sesi 3