Tabel angka menjawab pertanyaan, tetapi grafik yang membuat orang berhenti membaca dan mulai paham. matplotlib adalah mesin gambar di balik hampir seluruh grafik Python — termasuk metode .plot pada pandas yang kita pakai di chapter Analisis Data Eksploratif. Chapter ini membuka mesinnya langsung: anatomi kanvas, empat jenis grafik inti, dan cara menyimpan hasil yang layak dibagikan. Seluruh contoh diuji pada matplotlib 3.9.2 dan menulis file gambar — bukan memanggil plt.show() — agar skrip berjalan konsisten di server maupun laptop.

Anatomi: Figure dan Axes #

Dua istilah ini memisahkan seluruh kebingungan matplotlib. Figure adalah kanvas keseluruhan — jendela atau berkas gambar. Axes adalah satu panel grafik di dalam kanvas: sumbu, judul, dan titik-titik data. Satu Figure dapat memuat banyak Axes; setiap Axes digambar terpisah.

Matplotlib menyediakan dua gaya menulis kode. Gaya pyplot-state memakai fungsi global plt.plot(), plt.title(), dan kawan-kawannya yang diam-diam menunjuk “Axes aktif”:

python
import matplotlib.pyplot as plt

bulan = ["Januari", "Februari", "Maret"]
pengunjung = [1200, 1500, 1350]

plt.figure(figsize=(7, 4))
plt.plot(bulan, pengunjung, marker="o")
plt.title("Pengunjung Toko per Bulan")
plt.xlabel("Bulan")
plt.ylabel("Jumlah pengunjung")
plt.grid(True)
plt.savefig("cara-pyplot.png", dpi=150)

Kode tersebut menghasilkan grafik garis pengunjung dengan tiga titik bertanda bulat, judul di atas, label kedua sumbu, dan garis bantu grid. Gaya ini cepat untuk satu grafik, tetapi kejelasannya runtuh begita ada lebih dari satu panel — fungsi global selalu menunjuk panel terakhir.

Karena itu, konvensi yang kita anut di seluruh section ini adalah API berorientasi objek: ambil fig dan ax secara eksplisit lewat plt.subplots(), lalu semua perintah menjadi method pada objeknya sendiri:

python
import matplotlib.pyplot as plt
import pandas as pd

df = pd.read_csv("penjualan.csv")
df["total"] = df["harga"] * df["jumlah"]
bulanan = df.groupby(df["tanggal"].str[:7])["total"].sum()

fig, ax = plt.subplots(figsize=(7, 4))
ax.plot(bulanan.index, bulanan.values, marker="o", linewidth=2, color="#1f77b4", label="Total penjualan")
ax.set_title("Total Penjualan per Bulan")
ax.set_xlabel("Bulan")
ax.set_ylabel("Total (Rp)")
ax.grid(True, linestyle="--", alpha=0.5)
ax.legend()
ax.yaxis.set_major_formatter(lambda nilai, posisi: f"{nilai / 1_000_000:.1f} jt")
fig.tight_layout()
fig.savefig("penjualan_bulanan.png", dpi=150)
print("Grafik tersimpan: penjualan_bulanan.png")

Output yang Dihasilkan:

text
Grafik tersimpan: penjualan_bulanan.png

Mari kita bedah baris-baris kuncinya:

  1. Baris 8 (fig, ax = plt.subplots(figsize=(7, 4))): membuat Figure berukuran 7×4 inci beserta satu Axes; fig mengurus kanvas, ax mengurus panel.
  2. Baris 9 (ax.plot(...)): menggambar garis dari index bulan (2025-01 dst.) dan nilai totalnya, dengan penanda titik, tebal garis, warna heksadesimal, dan label untuk legend.
  3. Baris 10-13 (ax.set_title dst.): seluruh elemen teks adalah method ax — judul, label sumbu X dan Y, grid putus-putus setengah transparan, dan legend yang membaca label dari ax.plot.
  4. Baris 14 (ax.yaxis.set_major_formatter(...)): memformat tanda sumbu Y menjadi juta rupiah (5.0 jt) agar angka besar tetap terbaca.
  5. Baris 15-16 (fig.tight_layout() dan fig.savefig(...)): merapikan jarak antar elemen lalu menulis kanvas ke berkas PNG beresolusi 150 dpi.

Grafik yang tersimpan menampilkan tiga titik data: Rp4.985.000 (Januari), Rp5.477.000 (Februari), dan Rp3.915.000 (Maret) — kenaikan kecil lalu penurunan tajam ke Maret, dengan label sumbu Y dalam format jutaan.

Empat Jenis Grafik Dasar #

Hampir semua kebutuhan presentasi tercakup empat jenis grafik: garis untuk tren, scatter untuk hubungan dua variabel, batang untuk perbandingan kategori, dan histogram untuk sebaran. Ketiga panel berikut digambar dalam satu Figure lewat plt.subplots(nrows=1, ncols=3):

python
import matplotlib.pyplot as plt
import pandas as pd

df = pd.read_csv("penjualan.csv")
df["total"] = df["harga"] * df["jumlah"]

fig, axes = plt.subplots(nrows=1, ncols=3, figsize=(12, 3.5))

axes[0].scatter(df["harga"], df["jumlah"])
axes[0].set_title("Harga vs Jumlah")
axes[0].set_xlabel("Harga (Rp)")
axes[0].set_ylabel("Jumlah unit")

kategori_total = df.groupby("kategori")["total"].sum()
axes[1].bar(kategori_total.index, kategori_total.values, color="#2ca02c")
axes[1].set_title("Total per Kategori")
axes[1].set_xlabel("Kategori")
axes[1].set_ylabel("Total (Rp)")

axes[2].hist(df["jumlah"], bins=6, color="#ff7f0e", edgecolor="black")
axes[2].set_title("Distribusi Jumlah per Transaksi")
axes[2].set_xlabel("Jumlah unit")
axes[2].set_ylabel("Frekuensi")

fig.tight_layout()
fig.savefig("tiga_jenis_grafik.png", dpi=150)
print("Grafik tersimpan: tiga_jenis_grafik.png")

Output yang Dihasilkan:

text
Grafik tersimpan: tiga_jenis_grafik.png

Karena ncols=3, variabel axes menjadi array tiga objek Axes yang diakses axes[0], axes[1], axes[2]. Panel kiri berupa diagram pencar yang memperlihatkan titik-titik menurun: transaksi barang mahal cenderung berisi lebih sedikit unit — bukti visual korelasi -0,63 dari chapter EDA. Panel tengah menampilkan diagram batang dengan Elektronik tertinggi. Panel kanan berupa histogram dengan puncak di nilai jumlah 2-4 dan ekor hingga 8.

Pemilihan jenis grafik mengikuti pertanyaan:

PertanyaanJenis grafikMethod Axes
Bagaimana tren dari waktu ke waktu?lineax.plot()
Bagaimana hubungan dua variabel?scatterax.scatter()
Mana yang terbesar antar kategori?barax.bar()
Bagaimana sebaran satu variabel?histogramax.hist()

Warna, Style, dan Menyimpan ke File #

Mengatur setiap warna dan grid satu per satu lelah dibaca. Daftar style siap pakai mengubah tampilan seluruh grafik dalam satu baris:

python
import matplotlib.pyplot as plt
import pandas as pd

plt.style.use("seaborn-v0_8-whitegrid")

df = pd.read_csv("penjualan.csv")
df["total"] = df["harga"] * df["jumlah"]
bulanan = df.groupby(df["tanggal"].str[:7])["total"].sum()

fig, ax = plt.subplots(figsize=(7, 4))
ax.plot(bulanan.index, bulanan.values, marker="s", color="crimson")
ax.set_title("Total Penjualan per Bulan (style seaborn-v0_8-whitegrid)")
ax.set_xlabel("Bulan")
ax.set_ylabel("Total (Rp)")
fig.tight_layout()
fig.savefig("penjualan_bulanan_style.png", dpi=150)
fig.savefig("penjualan_bulanan_style.pdf")
fig.savefig("penjualan_bulanan_style.svg")
print("Tersimpan: penjualan_bulanan_style.png, .pdf, dan .svg")

Output yang Dihasilkan:

text
Tersimpan: penjualan_bulanan_style.png, .pdf, dan .svg

Satu panggilan plt.style.use() menghasilkan grafik dengan latar putih bersih dan grid halus ala seaborn; penanda titik berubah jadi persegi dan garis berwarna crimson. Tiga pemanggilan fig.savefig() menulis gambar yang sama ke tiga format: PNG untuk tampilan di layar dan dokumen, PDF untuk dicetak, dan SVG yang dapat disunting di aplikasi desainer karena berbasis vektor.

Kapan Matplotlib, Kapan Seaborn #

Matplotlib memberi kendali penuh: setiap titik, warna, dan anotasi dapat diatur satu per satu. Harga yang dibayar adalah verbositas — setiap elemen estetika harus diperintah eksplisit. Panduan singkatnya:

SituasiPilihan
Grafik publikasi dengan penyesuaian detail penuhmatplotlib
Prototipe cepat di tengah analisismetode .plot pandas
Grafik statistik dengan tampilan rapi otomatisseaborn

Chapter berikutnya memperkenalkan seaborn — lapisan statistical plotting di atas matplotlib yang menghapus sebagian besar boilerplate di atas tanpa mengorbankan akses ke ax ketika tetap dibutuhkan.