DataLens

Box, violin, dan grafik distribusi

Bandingkan bagaimana nilai tersebar di berbagai kelompok dengan box, violin dan strip plot, baca box plot dengan benar, dan tambahkan distribusi marginal.

Level: Menengah · 8 menit baca

Latihan modul ini

Soal-soal untuk pelajaran ini berjalan di browser-mu dan langsung mengecek jawabanmu.

Idenya

Rata-rata menyembunyikan banyak hal. Dua toko bisa sama-sama punya rata-rata Rp 400.000 per order: satu dengan setiap order di sekitar Rp 400.000, yang lain dengan banyak order kecil dan beberapa order yang sangat besar. Keduanya butuh strategi berbeda. Grafik distribusi menunjukkan seluruh sebaran, bukan hanya bagian tengahnya.

Kamu sudah bertemu histogram. Modul ini menambahkan alat untuk membandingkan distribusi antar kelompok: box plot, violin plot dan strip plot.

import pandas as pd
import plotly.express as px

sales = pd.read_csv("sales.csv")
completed = sales[sales["status"] == "completed"]
orders = (completed.groupby(["order_id", "channel", "segment"], as_index=False)["revenue"].sum()
          .rename(columns={"revenue": "order_value"}))
print(orders.head())
print(orders.groupby("channel")["order_value"].describe().round(0))
   order_id channel   segment  order_value
0         1     app  Business        89000
1         2     web  Consumer       285000
2         3     app  Consumer       960000
3         4     app  Consumer       195000
4         5     app  Consumer        75000
         count      mean       std      min       25%       50%       75%        max
channel
app       10.0  473400.0  385090.0  75000.0  116250.0  349500.0  834000.0  1024000.0
web       16.0  443875.0  264994.0  89000.0  281250.0  375000.0  666250.0   918000.0

describe() memberi angka-angkanya; grafik di bawah membuatnya terlihat.

Box plot

Apakah pesanan lewat aplikasi biasanya lebih besar daripada lewat website? Rata-rata memberimu satu angka per channel, tapi menyembunyikan seberapa tersebar pesanannya dan apakah ada beberapa pesanan raksasa yang menariknya naik. Box plot menampilkan seluruh distribusi setiap kelompok, berdampingan:

fig = px.box(orders, x="channel", y="order_value", title="Order value by channel")
fig.show()

Cara membaca sebuah box:

BagianMenunjukkan
garis di dalam boxmedian (separuh order di bawahnya, separuh di atasnya)
tepi boxpersentil ke-25 dan ke-75: 50% order di tengah (interquartile range, IQR)
whiskerrentang nilai "normal", sampai 1,5 × IQR di luar box
titik di luar whiskeroutlier: nilai yang luar biasa kecil atau besar

Box plot memadatkan sebuah distribusi menjadi lima angka, sehingga beberapa kelompok mudah dibandingkan berdampingan. Arahkan kursor ke sebuah box untuk melihat angka persisnya.

Tampilkan juga titik-titiknya

Dengan kelompok kecil (di sini, 10 order app), sebuah box bisa menyembunyikan betapa sedikitnya titik data. points="all" menggambar setiap observasi di samping box:

fig = px.box(orders, x="channel", y="order_value", points="all",
             hover_data=["order_id"], title="Order value by channel")
fig.show()
print(fig.data[0].boxpoints)
all
Ide utama

Selalu ketahui n-mu (jumlah titik per kelompok). Box yang digambar dari 5 order terlihat sama meyakinkannya dengan box dari 5.000 order. Menampilkan titik-titiknya, atau menaruh n di label, menjaga grafiknya tetap jujur.

Strip plot: hanya titik-titiknya

Untuk data kecil, strip plot (setiap titik, digeser sedikit ke samping supaya tidak bertumpuk) sering lebih jelas daripada box:

fig = px.strip(orders, x="channel", y="order_value", color="segment",
               title="Every completed order")
fig.show()

Violin plot: bentuknya

Violin adalah histogram yang dihaluskan dan dicerminkan di kedua sisi, sehingga kamu bisa melihat di mana nilai-nilai mengumpul (bagian yang lebar) dan apakah ada dua punuk. box=True menggambar box kecil di dalamnya:

fig = px.violin(orders, x="segment", y="order_value", box=True, points="all",
                title="Order value by segment")
fig.show()
print(fig.data[0].type, fig.data[0].box.visible)
violin True

Violin butuh data dalam jumlah yang cukup supaya bermakna; pada segelintir titik, penghalusannya mengarang bentuk yang sebenarnya tidak ada. Pakai untuk ratusan observasi, dan box serta strip untuk yang lebih sedikit.

Histogram dengan grafik marginal

Histogram bisa membawa grafik distribusi kecil di sepanjang tepinya:

fig = px.histogram(orders, x="order_value", nbins=8, marginal="box",
                   title="Distribution of completed order values")
fig.show()
print([t.type for t in fig.data])
['histogram', 'box']

Histogram menunjukkan bentuknya, box marginal menandai median dan outlier. marginal juga menerima "violin" dan "rug" (satu garis kecil per nilai). Scatter plot mendukung marginal_x dan marginal_y dengan cara yang sama.

Histogram bertumpuk untuk dua kelompok

Kalau kamu lebih suka melihat bentuk utuh setiap kelompok daripada kotak ringkasan, kamu bisa menggambar kedua histogram di sumbu yang sama. Membuat bar-barnya agak transparan memungkinkanmu melihat di mana keduanya tumpang tindih:

fig = px.histogram(orders, x="order_value", color="channel", nbins=8,
                   barmode="overlay", opacity=0.6)
fig.show()

barmode="overlay" dengan sedikit transparansi membuat kedua distribusi sama-sama terlihat. Dengan ukuran kelompok yang sangat berbeda, tambahkan histnorm="percent" supaya bar setiap kelompok berjumlah 100%, membandingkan bentuk alih-alih jumlah.

Yang mana?

PertanyaanGrafik
Seperti apa distribusi satu angka?histogram (+ marginal="box")
Bagaimana beberapa kelompok dibandingkan?box plot
... dan kelompoknya kecil?box dengan points="all", atau strip
... dan kelompoknya besar, bentuknya penting?violin

Mengapa ini penting untuk kode yang bersih

Hanya melaporkan rata-rata adalah versi analitik dari menelan error: informasinya ada, tapi tersembunyi. Box atau strip plot di samping sebuah KPI menunjukkan sebaran, outlier dan ukuran sampelnya, sehingga keputusan tidak dibuat berdasarkan mean yang menyesatkan. Bangun tabel per observasi dulu (orders, satu baris per order), lalu pilih grafiknya, supaya kamu menggambar pada tingkat detail yang tepat.

Rangkuman

Latihan modul ini

Soal-soal untuk pelajaran ini berjalan di browser-mu dan langsung mengecek jawabanmu.

Berikutnya: Menyesuaikan layout (judul, legenda, margin) →