Idenya
Grafik bar dan histogram terlihat mirip, persegi panjang yang berjajar, tapi keduanya menjawab pertanyaan yang berbeda:
- Grafik bar membandingkan kategori: revenue per kategori produk, order per kota.
- Histogram menunjukkan distribusi satu angka: bagaimana nilai order tersebar, berapa banyak order yang jatuh antara Rp 100.000 dan Rp 200.000.
Modul ini memakai baris order Toko Kita, sales.csv:
import pandas as pd
import plotly.express as px
sales = pd.read_csv("sales.csv")
completed = sales[sales["status"] == "completed"]
print(completed[["product", "category", "quantity", "revenue", "channel"]].head(3))
product category quantity revenue channel
0 Desk Organizer Stationery 1 89000 app
1 Arabica Gayo 250g Coffee 3 285000 web
2 Pour-over Kettle Kitchen 3 960000 app
Grafik bar dari data yang sudah diagregasi
Pertanyaan pertama manajer biasanya "kategori mana yang paling menghasilkan?". Itu perbandingan antar kategori, jadi grafik bar cocok. Satu hal yang perlu diketahui: px.bar menggambar satu bar per baris DataFrame yang kamu berikan. Data penjualan berisi satu baris per baris order, jadi kamu menjumlahkan revenue per kategori dulu, baru membuat grafik dari hasilnya:
by_category = (completed.groupby("category", as_index=False)["revenue"].sum()
.sort_values("revenue", ascending=False))
fig = px.bar(by_category, x="category", y="revenue", title="Completed revenue by category")
fig.show()
Dua kebiasaan sudah ada di kode ini:
- Agregasikan di pandas, gambar di Plotly. Grafiknya mendapat tepat satu baris per bar.
- Urutkan bar-nya. Kecuali kategorinya punya urutan alami (ukuran, bulan, rating), urutkan berdasarkan nilai supaya peringkatnya langsung terlihat.
Kalau kamu memberikan baris yang belum diagregasi, px.bar menumpuk satu segmen tipis per baris. Hasilnya terlihat hampir benar, tapi saat di-hover muncul puluhan irisan. Agregasikan dulu.
Bar horizontal untuk label panjang
Nama produk itu panjang. Label yang diputar sulit dibaca; bar horizontal tidak:
by_product = (completed.groupby("product", as_index=False)["revenue"].sum()
.sort_values("revenue"))
fig = px.bar(by_product, x="revenue", y="product", orientation="h",
title="Completed revenue by product")
fig.show()
Tukar x dan y, dan atur orientation="h". Perhatikan pengurutannya menaik di sini: Plotly menggambar baris pertama di bawah, jadi urutan menaik menaruh bar terbesar di atas.
Label di bar
text_auto=True menuliskan nilai setiap bar di atasnya. Format string mengatur caranya:
fig = px.bar(by_category, x="category", y="revenue", text_auto=".3s",
title="Completed revenue by category")
fig.show()
print(fig.data[0].texttemplate)
%{y:.3s}
.3s berarti "3 angka penting dengan akhiran SI", jadi 5113000 tampil sebagai 5.11M. Dengan nilai di bar, pembaca tidak perlu menelusuri garis grid, dan sering kali kamu bahkan bisa menghilangkan sumbu y.
Dua kategori: berkelompok atau bertumpuk
Pertanyaan berikutnya sering kali "lalu bagaimana pembagiannya antara website dan aplikasi?". Kamu bisa menampilkan kategori kedua di dalam setiap bar dengan mewarnainya, memakai color=:
by_cat_channel = completed.groupby(["category", "channel"], as_index=False)["revenue"].sum()
fig = px.bar(by_cat_channel, x="category", y="revenue", color="channel",
title="Revenue by category and channel")
fig.show()
print(fig.layout.barmode)
relative
Express secara default menumpuk bar berwarna (barmode="relative"). Bar bertumpuk menunjukkan total dan kontribusi setiap bagian. Untuk membandingkan bagian-bagiannya satu sama lain, taruh berdampingan:
fig = px.bar(by_cat_channel, x="category", y="revenue", color="channel",
barmode="group", title="Revenue by category and channel")
fig.show()
| Pakai | Saat pertanyaannya |
|---|---|
bertumpuk (barmode="relative") | "Berapa totalnya, dan terdiri dari apa?" |
berkelompok (barmode="group") | "Apakah web lebih besar dari app di setiap kategori?" |
Histogram: bentuk dari satu angka
Jenis pertanyaan yang berbeda: apakah sebagian besar pesanan kecil, besar, atau di tengah-tengah? Sekarang kamu tidak membandingkan kategori, tapi melihat sebaran satu angka di semua pesanan. Itulah yang ditunjukkan histogram:
fig = px.histogram(completed, x="revenue", nbins=10, title="Order line values")
fig.show()
px.histogram menerima baris mentah (tanpa diagregasi dulu): ia mengelompokkan nilai ke dalam bin (rentang) dan menghitung baris di setiap bin. nbins menyarankan berapa banyak bin yang dipakai. Bentuknya bercerita: sebagian besar baris bernilai kecil, dengan ekor panjang berisi beberapa yang besar. Bentuk "condong ke kanan" itu khas untuk data uang, dan itulah sebabnya median sering menggambarkan order "biasa" lebih baik daripada mean.
Histogram juga bisa menjumlahkan alih-alih menghitung, sehingga menjadi grafik bar cepat dari baris mentah:
fig = px.histogram(completed, x="category", y="revenue", histfunc="sum",
title="Revenue by category (from raw rows)")
fig.show()
Itu praktis untuk eksplorasi. Untuk grafik final, agregasikan secara eksplisit di pandas, supaya angkanya mudah diperiksa.
Bar harus dimulai dari nol
Panjang sebuah bar menyandikan nilainya. Kalau sumbunya dimulai dari 1.000.000 alih-alih 0, bar untuk 2.000.000 terlihat dua kali lebih panjang daripada bar untuk 1.500.000, padahal hanya sepertiga lebih besar. Plotly memulai sumbu bar dari nol secara default; jangan ubah itu untuk bar. (Grafik garis berbeda: ia menyandikan perubahan, jadi sumbu yang di-zoom bisa saja tidak masalah.)
Mengapa ini penting untuk kode yang bersih
Kode grafik yang paling bersih punya tiga langkah yang terlihat: filter (completed), agregasi (groupby + sum, terurut), gambar (satu pemanggilan px.bar). Setiap langkah bisa diperiksa sendiri, dan grafiknya tidak bisa diam-diam menghitung dobel, karena kamu sudah melihat tabel hasil agregasinya sebelum menggambar.
Rangkuman
- Grafik bar = membandingkan kategori; histogram = distribusi satu angka.
- Agregasikan di pandas, lalu
px.bar; urutkan bar berdasarkan nilai kecuali urutannya alami. orientation="h"(dengan x dan y ditukar) untuk label panjang; urutkan menaik supaya yang terbesar di atas.text_auto=Trueatau format seperti".3s"memberi label pada bar.color=memecah bar; bertumpuk secara default,barmode="group"untuk berdampingan.px.histogram(df, x=..., nbins=...)mengelompokkan nilai mentah ke bin; sumbu bar dimulai dari nol.