Method .plot() yang kita pakai sehari-hari sebenarnya hanyalah lapisan muka: setiap panggilan .plot.line() atau .plot.bar() langsung menghasilkan objek Matplotlib yang siap disempurnakan. Lapisan ini membuat plot dasar terasa sekali baris, sedangkan seluruh kekuatan styling Matplotlib tetap terbuka lewat objek Axes dan Figure yang dikembalikannya. Pada Chapter ini kita membedah arsitektur dua lapis tersebut, menyempurnakan plot dengan API Matplotlib, dan menentukan kapan lebih baik menggambar langsung dengan Matplotlib murni.

Arsitektur Dua Lapis: pandas dan Matplotlib #

pandas tidak memiliki mesin penggambar sendiri. Method .plot() milik DataFrame dan Series menyusun data, warna, dan label dari kolom tabel, lalu mendelegasikan seluruh penggambaran ke Matplotlib. Hasilnya adalah objek matplotlib.axes.Axes — bukan gambar mati — sehingga kita bisa melanjutkannya dengan method Matplotlib mana pun.

Dua komponen paling penting untuk dikenali:

KomponenPeranContoh method
Figurekanvas seluruh gambar, bisa memuat beberapa plotfig.savefig(), fig.set_size_inches()
Axessatu area plot beserta sumbu, judul, dan legendax.set_title(), ax.set_xlabel(), ax.bar()

Konvensi ax = df.plot... lalu menyunting ax adalah pola resmi yang dijalankan pada backend non-interaktif seperti Agg maupun di Jupyter.

Menyempurnakan Plot dari DataFrame #

Contoh berikut mengambil data penjualan bulanan Toko Amanah, menggambar plot garis dengan pandas, lalu menyempurnakan judul dan label sumbu lewat API Matplotlib. Karena lingkungan uji kita berjalan tanpa layar, plot disimpan sebagai berkas PNG dengan fig.savefig().

python
import os

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import pandas as pd

bulanan = pd.DataFrame({
    "bulan": ["Jan", "Feb", "Mar", "Apr"],
    "penjualan": [120, 135, 150, 142],
    "target": [125, 130, 140, 145],
})

# 1. Plot garis lewat method .plot.line() milik pandas
ax = bulanan.plot.line(x="bulan", y="penjualan", marker="o")
ax.set_title("Penjualan Bulanan Toko Amanah")
ax.set_xlabel("Bulan")
ax.set_ylabel("Juta Rupiah")
fig = ax.get_figure()
fig.savefig("tren_penjualan.png", dpi=100, bbox_inches="tight")
print("line  ->", type(ax).__name__, "| judul:", ax.get_title())
print("label x:", ax.get_xlabel(), "| label y:", ax.get_ylabel())

# 2. Plot batang dua kolom sekaligus
axes = bulanan[["penjualan", "target"]].plot.bar()
axes.set_title("Penjualan vs Target")
fig2 = axes.get_figure()
fig2.savefig("penjualan_target.png", dpi=100)
legenda = [t.get_text() for t in axes.get_legend().get_texts()]
print("bar   ->", type(axes).__name__, "| legenda:", legenda)

# 3. Kendali penuh lewat matplotlib murni
fig3, ax3 = plt.subplots(figsize=(6, 4))
ax3.bar(bulanan["bulan"], bulanan["penjualan"], color="#2b7a3d")
ax3.set_title("Plot Manual dengan plt.subplots")
fig3.tight_layout()
fig3.savefig("plot_manual.png", dpi=100)
print("manual->", type(ax3).__name__)

for nama in ("tren_penjualan.png", "penjualan_target.png", "plot_manual.png"):
    os.remove(nama)
plt.close("all")
print("3 PNG sementara selesai dibuat lalu dihapus")

Output yang Dihasilkan:

text
line  -> Axes | judul: Penjualan Bulanan Toko Amanah
label x: Bulan | label y: Juta Rupiah
bar   -> Axes | legenda: ['penjualan', 'target']
manual-> Axes
3 PNG sementara selesai dibuat lalu dihapus

Mari kita telaah baris-baris pentingnya:

  1. Baris 15 (ax = bulanan.plot.line(...)): pandas membaca kolom bulan sebagai sumbu x dan penjualan sebagai sumbu y, menggambar garis dengan penanda titik, lalu mengembalikan objek Axes.
  2. Baris 16-18 (ax.set_title(...), ax.set_xlabel(...), ax.set_ylabel(...)): tiga method Matplotlib menetapkan judul dan label sumbu; nama kolom tidak lagi otomatis karena kita mengambil alih kendali.
  3. Baris 19-20 (fig = ax.get_figure(), fig.savefig(...)): get_figure() menaikkan satu level dari Axes ke Figure induknya, dan savefig() menuliskan hasilnya ke berkas PNG.
  4. Baris 25 (axes = bulanan[["penjualan", "target"]].plot.bar()): memilih dua kolom sekaligus membuat pandas menggambar dua kelompok batang dan menghidupkan legend dengan label penjualan dan target.
  5. Baris 29 (axes.get_legend().get_texts()): kita membaca kembali teks legend dari objek Matplotlib — bukti bahwa objek tersebut bisa diintip dan diubah sesudah plot dibuat.
  6. Baris 33-34 (plt.subplots(...), ax3.bar(...)): pola Matplotlib murni; plt.subplots() membuat Figure dan Axes kosong, dan kita mengisi Axes itu sendiri dengan ax3.bar().

Memilih Tingkat Kendali #

KebutuhanAlat yang tepat
Plot cepat dari kolom tabeldf.plot.line(), df.plot.bar(), df.plot.hist()
Mengatur judul, label, warna, skala sumbuobjek Axes hasil .plot()
Tata letak multi-panel, anotasi khusus, plot campuranplt.subplots() dan gambar manual per Axes

Aturan praktisnya: mulai dari .plot(), naikkan kendali satu level ke Axes saat perlu penyesuaian, dan baru turun ke plt.subplots() ketika tata letak halaman gambar ikut diatur. Ketiga tingkat itu bisa dicampur dalam satu skrip karena semuanya berakhir pada objek Matplotlib yang sama.

Contoh di atas masih menyusun sendiri nilai statistiknya — mean, distribusi, dan garis tren kita hitung manual atau tidak digambar sama sekali. Chapter berikutnya memperkenalkan seaborn, library yang menempel di atas Matplotlib ini dan menghitung agregasi statistik secara otomatis langsung dari DataFrame.

Referensi resmi untuk pendalaman: dokumentasi Matplotlib , panduan visualisasi pandas , dan pandas.DataFrame.plot .