DataLens

Faceting (small multiples)

Pecah satu grafik yang penuh sesak menjadi grid grafik kecil yang bisa dibandingkan dengan facet_col dan facet_row, dan atur sumbu bersama serta judul panel.

Level: Menengah · 7 menit baca

Latihan modul ini

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

Idenya

Taruh revenue bulanan lima kategori di satu grafik garis dan kamu mendapat spageti: lima garis kusut, legenda yang harus diterjemahkan, dan tidak ada yang bisa mengikuti Stationery. Faceting (disebut juga small multiples) menggambar grafik yang sama sekali per kategori, berdampingan, dengan skala yang sama. Setiap panel sederhana, dan membandingkannya mudah karena mata melompat di antara tata letak yang identik.

Express membuatnya cukup satu argumen: facet_col=.

import pandas as pd
import plotly.express as px

sales = pd.read_csv("sales.csv")
completed = sales[sales["status"] == "completed"]
monthly_cat = (completed.assign(month=completed["order_date"].str[:7])
               .groupby(["month", "category"], as_index=False)["revenue"].sum())
print(monthly_cat.head())
print(len(monthly_cat))
     month    category  revenue
0  2024-01      Coffee   285000
1  2024-01        Home   270000
2  2024-01     Kitchen   960000
3  2024-01  Stationery   178000
4  2024-02      Coffee   635000
24

Spageti dulu

Cara yang paling jelas untuk menampilkan revenue bulanan lima kategori adalah satu grafik garis dengan lima garis berwarna. Coba dan lihat seberapa mudah dibaca:

fig = px.line(monthly_cat, x="month", y="revenue", color="category", markers=True,
              title="Revenue by category (one chart)")
fig.show()

Lima garis yang saling bersilangan. Kamu bisa membaca yang terbesar, tapi kategori yang lebih kecil tenggelam.

facet_col: satu panel per kategori

Sekarang data yang sama, tapi alih-alih lima garis di satu grafik, setiap kategori mendapat grafik kecilnya sendiri, berdampingan. Satu-satunya perubahan adalah facet_col= alih-alih color=:

fig = px.line(monthly_cat, x="month", y="revenue", facet_col="category", markers=True,
              title="Revenue by category (small multiples)")
fig.show()
print(len(fig.data), [a.text for a in fig.layout.annotations])
5 ['category=Coffee', 'category=Home', 'category=Kitchen', 'category=Stationery', 'category=Electronics']

Setiap kategori mendapat panelnya sendiri (dan trace-nya sendiri). Panel-panel berbagi sumbu y, jadi garis yang tinggi memang kategori yang besar, dan bentuknya mudah dibandingkan: kategori mana yang tumbuh, mana yang stabil, mana yang punya satu bulan besar.

Membungkus menjadi grid

Lima panel dalam satu baris menjadi sempit. facet_col_wrap memulai baris baru setelah N panel:

fig = px.line(monthly_cat, x="month", y="revenue", facet_col="category",
              facet_col_wrap=3, markers=True, height=500)
fig.show()

facet_row= memecah menjadi baris berdasarkan variabel lain. Gabungkan keduanya untuk grid dari dua variabel, misalnya kategori × channel:

monthly_cat_ch = (completed.assign(month=completed["order_date"].str[:7])
                  .groupby(["month", "category", "channel"], as_index=False)["revenue"].sum())
fig = px.bar(monthly_cat_ch, x="month", y="revenue", facet_col="category", facet_row="channel",
             height=450)
fig.show()

Sumbu bersama atau independen

Secara default, facet berbagi sumbu. Itu biasanya benar: inti small multiples adalah membandingkan yang sejenis. Tapi saat satu panel jauh lebih besar dari yang lain, panel kecil menjadi garis datar. Kalau kamu lebih peduli pada bentuk setiap panel daripada ukurannya, bebaskan sumbu y-nya:

fig = px.line(monthly_cat, x="month", y="revenue", facet_col="category",
              facet_col_wrap=3, markers=True, height=500)
fig.update_yaxes(matches=None, showticklabels=True)
fig.show()

matches=None memutus tautan sumbunya, dan showticklabels=True menampilkan skala masing-masing panel (yang secara default disembunyikan di panel bagian dalam).

Awas

Sumbu independen membuat setiap panel terlihat sama pentingnya. Kategori dengan revenue Rp 50.000 bisa terlihat sedramatis kategori dengan Rp 5.000.000. Saat kamu membebaskan sumbunya, nyatakan di judul atau subjudul.

Judul panel yang lebih bersih

Express memberi judul setiap panel category=Coffee. Hapus awalannya dengan for_each_annotation, yang menjalankan sebuah fungsi pada setiap anotasi (judul panel adalah anotasi):

fig = px.line(monthly_cat, x="month", y="revenue", facet_col="category", markers=True)
fig.for_each_annotation(lambda a: a.update(text=a.text.split("=")[-1]))
fig.show()
print([a.text for a in fig.layout.annotations])
['Coffee', 'Home', 'Kitchen', 'Stationery', 'Electronics']

Mengurutkan panel

Panel mengikuti urutan data kecuali kamu mengatur category_orders. Taruh panel terpenting di depan, atau ikuti urutan alami:

order = (monthly_cat.groupby("category")["revenue"].sum()
         .sort_values(ascending=False).index.tolist())
fig = px.line(monthly_cat, x="month", y="revenue", facet_col="category",
              category_orders={"category": order}, markers=True)
fig.for_each_annotation(lambda a: a.update(text=a.text.split("=")[-1]))
fig.show()
print(order)
['Electronics', 'Kitchen', 'Coffee', 'Home', 'Stationery']

Facet atau warna?

Pakai warna (satu grafik) saatPakai facet saat
2-3 kelompok4+ kelompok
garis jarang bersilangangaris tumpang tindih dan kusut
perbandingan persis di setiap x pentingbentuk keseluruhan setiap kelompok penting

Mengapa ini penting untuk kode yang bersih

Faceting memindahkan kerumitan dari grafik ke tata letak yang konsisten. Di kode, artinya satu pemanggilan px dengan facet_col= alih-alih loop yang membangun lima figure dengan lima set format yang perlahan menyimpang. Data yang sama, fungsi yang sama, gaya yang sama untuk setiap panel: satu sumber kebenaran untuk seluruh grid.

Rangkuman

Latihan modul ini

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

Berikutnya: Box, violin, dan grafik distribusi →