Angka perubahan pada Bagian 2 sudah bercerita, tetapi tabel 23 baris perubahan dan 12 baris moving average harus dibaca pelan-pelan untuk menangkap polanya. Grafik mengerjakan pekerjaan itu dalam sekejap mata: arah tren, kecuraman, gejolak, dan posisi relatif tiga komoditas terlihat sekilas. Sesuai panduan chapter Memilih Visualisasi, tiga pertanyaan kita meminta tiga jenis gambar — line chart untuk pergerakan waktu, histogram untuk sebaran perubahan bulanan, dan box plot untuk perbandingan kelompok. Ketiganya digambar dari dataset bersih Bagian 1, dan setiap grafik disertai angka tercetak yang dapat diverifikasi.
Line Chart Tiga Komoditas #
Dua puluh empat bulan ketiga komoditas digambar pada satu sumbu. Label bulan ditampilkan setiap tiga bulan agar sumbu-x tidak padat, penanda titik memperlihatkan nilai data, dan kotak keterangan dari plt.legend() memisahkan tiga garis:
import matplotlib.pyplot as plt
beras = [12500, 12800, 12700, 13100, 13400, 13300, 13600, 13900, 13800, 14200, 14500, 14400,
14600, 14500, 14800, 15000, 14900, 15200, 15400, 15600, 15500, 15800, 16000, 15900]
gula = [16000, 16200, 16100, 16400, 16600, 16500, 16800, 17000, 16900, 17200, 17400, 17300,
17500, 17650, 17800, 18000, 17900, 18200, 18400, 18600, 18500, 18800, 19000, 18900]
minyak = [15600, 15800, 15700, 16000, 16200, 16100, 16400, 16600, 16500, 16800, 17000, 16900,
17100, 17200, 17400, 17300, 17500, 17600, 17800, 17850, 17900, 18100, 18000, 18300]
bulan = [f"2025-{m:02d}" for m in range(1, 13)] + [f"2026-{m:02d}" for m in range(1, 13)]
nomor = list(range(1, 25))
plt.figure(figsize=(8, 4))
plt.plot(nomor, beras, marker="o", label="beras")
plt.plot(nomor, gula, marker="s", label="gula pasir")
plt.plot(nomor, minyak, marker="^", label="minyak goreng")
plt.xticks(nomor[::3], [bulan[i] for i in range(0, 24, 3)], rotation=45)
plt.xlabel("Bulan")
plt.ylabel("Harga (Rp/kg)")
plt.title("Harga Tiga Komoditas, Jan 2025 - Des 2026")
plt.legend()
plt.grid(True)
plt.savefig("harga_komoditas_line.png")
plt.close()
for nama, data in [("beras", beras), ("gula pasir", gula), ("minyak goreng", minyak)]:
naik = (data[23] - data[0]) / data[0] * 100
print(f"{nama:<13s}: {data[0]} menjadi {data[23]} Rp/kg (naik {naik:.2f}%)")Output yang Dihasilkan:
beras : 12500 menjadi 15900 Rp/kg (naik 27.20%)
gula pasir : 16000 menjadi 18900 Rp/kg (naik 18.12%)
minyak goreng: 15600 menjadi 18300 Rp/kg (naik 17.31%)Gambar yang tersimpan sebagai harga_komoditas_line.png memuat tiga garis menanjak yang tidak saling bersilang: gula pasir di posisi teratas sejak awal (16000 menjadi 18900), minyak goreng di tengah (15600 menjadi 18300), dan beras di bawah (12500 menjadi 15900). Yang paling mencolok adalah kecuraman garis beras — meskipun levelnya terendah, kenaikannya 27.20 persen, hampir sepuluh poin di atas dua komoditas lain, sehingga garisnya menanjak paling tajam dan jaraknya ke minyak goreng menyempit dari 3100 Rp menjadi 2400 Rp. Ketiga garis juga bergerak bergerigi naik — penurunan tipis tiap tiga bulan yang oleh Bagian 2 sudah dihitung — dengan gerigi paling terlihat pada beras.
Histogram Perubahan Bulanan Beras #
Line chart memperlihatkan level; histogram berikut membedah laju perubahannya. Bahan bakunya adalah 23 perubahan bulanan beras dari Bagian 2, dikelompokkan ke kelas lebar satu persen mulai batas −1:
import numpy as np
import matplotlib.pyplot as plt
beras = [12500, 12800, 12700, 13100, 13400, 13300, 13600, 13900, 13800, 14200, 14500, 14400,
14600, 14500, 14800, 15000, 14900, 15200, 15400, 15600, 15500, 15800, 16000, 15900]
perubahan = [(beras[i] - beras[i - 1]) / beras[i - 1] * 100 for i in range(1, len(beras))]
batas = [-1, 0, 1, 2, 3, 4]
jumlah, tepi = np.histogram(perubahan, bins=batas)
print("batas kelas (%) :", tepi.tolist())
print("frekuensi :", jumlah.tolist())
print("total bulan :", int(jumlah.sum()))
plt.figure()
plt.hist(perubahan, bins=batas, edgecolor="black")
plt.xlabel("Perubahan harga bulanan (%)")
plt.ylabel("Banyak bulan")
plt.title("Histogram Perubahan Bulanan Harga Beras")
plt.savefig("perubahan_beras_hist.png")
plt.close()Output yang Dihasilkan:
batas kelas (%) : [-1, 0, 1, 2, 3, 4]
frekuensi : [8, 0, 6, 8, 1]
total bulan : 23Frekuensi [8, 0, 6, 8, 1] memperlihatkan sebaran yang terbelah dua. Kelompok kiri berisi delapan bulan dengan perubahan antara −1 dan 0 persen — seluruh bulan turun, dan turunnya tipis semuanya. Kelompok kanan berisi lima belas bulan naik: enam bulan di kelas 1-2 persen, delapan bulan di kelas 2-3 persen, dan satu bulan di atas 3 persen (April 2025 dengan 3.15 persen). Kelas tengah 0-1 persen kosong — tidak ada satu pun bulan dengan kenaikan lebih kecil dari satu persen, sehingga pada histogram tampak celah yang memisahkan dua menara. Bentuk dua kelompok ini adalah tanda tangan pola musiman: harga bergerak dalam dua mode saja, naik jelas atau turun tipis, tanpa wilayah abu-abu di antaranya.
Box Plot Perbandingan Tiga Komoditas #
Pertanyaan penutup visualisasi: bagaimana sebaran level 24 bulan ketiga komoditas dibandingkan? Box plot menjawab dengan memadatkan setiap komoditas menjadi kotak kuartil, garis median, dan whisker. Nilai median dan jumlah outlier (titik di luar whisker) diambil langsung dari objek gambar matplotlib, lalu dicetak sebagai verifikasi:
import matplotlib.pyplot as plt
beras = [12500, 12800, 12700, 13100, 13400, 13300, 13600, 13900, 13800, 14200, 14500, 14400,
14600, 14500, 14800, 15000, 14900, 15200, 15400, 15600, 15500, 15800, 16000, 15900]
gula = [16000, 16200, 16100, 16400, 16600, 16500, 16800, 17000, 16900, 17200, 17400, 17300,
17500, 17650, 17800, 18000, 17900, 18200, 18400, 18600, 18500, 18800, 19000, 18900]
minyak = [15600, 15800, 15700, 16000, 16200, 16100, 16400, 16600, 16500, 16800, 17000, 16900,
17100, 17200, 17400, 17300, 17500, 17600, 17800, 17850, 17900, 18100, 18000, 18300]
label = ["beras", "gula pasir", "minyak goreng"]
plt.figure()
kotak = plt.boxplot([beras, gula, minyak], tick_labels=label)
plt.ylabel("Harga (Rp/kg)")
plt.title("Box Plot Harga Tiga Komoditas (24 bulan)")
plt.savefig("harga_komoditas_boxplot.png")
plt.close()
for nama, median, pencilan in zip(label, kotak["medians"], kotak["fliers"]):
print(f"median {nama:<13s}: {median.get_ydata()[1]:8.2f} | pencilan: {len(pencilan.get_ydata())}")Output yang Dihasilkan:
median beras : 14500.00 | pencilan: 0
median gula pasir : 17450.00 | pencilan: 0
median minyak goreng: 17050.00 | pencilan: 0Gambar harga_komoditas_boxplot.png menyusun tiga kotak pada satu sumbu: kotak beras paling lebar (IQR 1700 Rp, dari Q1 13550 ke Q3 15250), gula pasir di tengah (IQR 1500), dan minyak goreng paling sempit (IQR 1300) — urutan yang persis mengikuti besar std pada Bagian 1. Median ketiganya (14500, 17450, 17050) berada dekat tengah kotaknya masing-masing. Tidak ada satu pun titik pencilan pada data bersih; sebagai pembanding, bila box plot digambar dari data mentah Bagian 1, angka 24000 akan tampil sebagai satu titik tersendiri jauh di atas kotak minyak goreng — whisker atasnya berhenti di batas 19600 (Q3 + 1.5 × IQR).
Tiga gambar kini melengkapi tiga tabel: level yang menanjak, laju yang terbelah dua kelompok, dan sebaran yang paling lebar pada beras. Seluruh bukti visual dan angka siap dirangkum menjadi temuan akhir pada Bagian 4.