Topik Analisis dan Visualisasi menutup proyek laporan lingkungan sekaligus menutup jalur ini, yaitu menjawab tiga pertanyaan lingkup dengan angka dan menyajikan satu gambar siap laporan. Skrip analisis.py membangun ulang data dengan generator yang sama, menghitung agregasi dan tabulasi silang untuk ketiga pertanyaan, mencetak kesimpulan yang menyebut nama ruangnya, lalu menyimpan diagram batang rata-rata suhu per ruang. Pada akhir topik, setiap pertanyaan pada topik Penentuan Lingkup Proyek memiliki jawaban yang terukur, dan seluruh mekanisme jalur pandas sudah dipraktikkan pada satu alur kerja utuh.
Skrip analisis.py yang mandiri#
Skrip analisis pada proyek ini berdiri sendiri, yaitu memanggil fungsi generator yang sama dengan pipeline.py alih-alih membaca berkas antar-topik. Sebabnya ada pada struktur topik, yaitu setiap topik berada di folder masing-masing sehingga ringkasan_ruang.csv yang dihasilkan topik Pembangunan Pipeline tidak otomatis tersedia di sini. Pada proyek nyata yang berkasnya berdampingan, skrip analisis cukup membaca berkas ringkasan tersebut dengan read_csv, dan hasilnya identik karena generatornya deterministik. Di sini generator dipanggil ulang agar skrip dapat dijalankan apa adanya.
Kemandirian semacam ini juga memudahkan pemeriksaan. Angka yang dicetak analisis.py dapat dibandingkan langsung dengan keluaran pipeline.py, karena keduanya berasal dari fungsi generator yang sama. Apabila ada angka yang berbeda, penyebabnya berada pada tahap analisis, bukan pada data yang berubah diam-diam.
Nama ruang dirapikan dan duplikat dibuang lebih dahulu, lalu skrip menghitung tiga tabel, yaitu jumlah bacaan suhu hilang per ruang sebelum pengisian, ringkasan statistik suhu setelah pengisian median, dan tabulasi silang ruang terhadap status_sensor dengan crosstab. Simpan berkas berikut pada folder kerja, lalu jalankan perintah pada blok bash di bawahnya.
# analisis.py: analisis akhir dan plot laporan dari data proyek yang sama.
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
def bangun_log() -> pd.DataFrame:
"""Membangun ulang log sensor 96 bacaan dengan kotoran deterministik."""
rng = np.random.default_rng(42)
n = 96
df = pd.DataFrame({
"waktu": pd.date_range("2026-01-05 07:00", periods=n, freq="15min"),
"ruang": rng.choice(["Lab A", "Lab B", "Ruang Arsip"], n, p=[0.4, 0.35, 0.25]),
"suhu_c": np.round(rng.normal(24, 1.5, n), 1),
"lembap_pct": np.round(rng.normal(60, 5, n), 1),
"status_sensor": rng.choice(["normal", "kalibrasi", "rusak"], n, p=[0.85, 0.10, 0.05]),
})
# kotoran 1: sebagian kecil sel suhu dan kelembapan menjadi NaN
df.loc[rng.random(n) < 0.05, "suhu_c"] = np.nan
df.loc[rng.random(n) < 0.05, "lembap_pct"] = np.nan
# kotoran 2: nama ruang tidak konsisten pada empat baris
df.loc[7, "ruang"] = "lab a"
df.loc[23, "ruang"] = "LAB B"
df.loc[41, "ruang"] = "ruang arsip"
df.loc[67, "ruang"] = " Lab A "
# kotoran 3: tiga baris digandakan
return pd.concat([df, df.sample(3, random_state=42)], ignore_index=True)
log = bangun_log()
# nama ruang dirapikan lebih dahulu agar pengelompokan tidak terpecah
log["ruang"] = log["ruang"].str.strip().str.title()
log = log.drop_duplicates()
# Pertanyaan b: jumlah bacaan suhu hilang per ruang, sebelum pengisian
hilang = log.assign(hilang=log["suhu_c"].isna()).groupby("ruang")["hilang"].sum().astype(int)
print(hilang)
# Pertanyaan a: kestabilan suhu per ruang, NaN diisi median ruangnya dahulu
log["suhu_c"] = log["suhu_c"].fillna(log.groupby("ruang")["suhu_c"].transform("median"))
ringkasan = (
log.groupby("ruang", as_index=False)
.agg(
suhu_rata=("suhu_c", "mean"),
suhu_std=("suhu_c", "std"),
jumlah_bacaan=("waktu", "size"),
)
.round(2)
)
print(ringkasan)
# Pertanyaan c: tabulasi silang ruang terhadap status sensor
crosstab = pd.crosstab(log["ruang"], log["status_sensor"])
print(crosstab)
# Kesimpulan terukur, angkanya diambil dari hasil perhitungan di atas
nama_tidak_stabil = ringkasan.loc[ringkasan["suhu_std"].idxmax(), "ruang"]
nilai_tidak_stabil = ringkasan["suhu_std"].max()
nama_rusak = crosstab["rusak"].idxmax()
jumlah_rusak = int(crosstab["rusak"].max())
print(f"Pertanyaan a: suhu paling tidak stabil di {nama_tidak_stabil}, simpangan baku {nilai_tidak_stabil:.2f} derajat Celsius")
print(f"Pertanyaan b: {int(hilang.sum())} bacaan suhu hilang, rinciannya pada tabel pertama")
print(f"Pertanyaan c: bacaan rusak terbanyak di {nama_rusak}, sebanyak {jumlah_rusak} bacaan")
# Satu plot laporan: diagram batang rata-rata suhu per ruang
ax = ringkasan.plot.bar(x="ruang", y="suhu_rata", legend=False, figsize=(6, 3.6))
ax.set_xlabel("Ruang")
ax.set_ylabel("Suhu rata-rata (°C)")
ax.set_title("Rata-rata suhu per ruang")
ax.get_figure().savefig("suhu-ruang.svg")
plt.close(ax.get_figure())
print("tersimpan suhu-ruang.svg")# menjalankan analisis akhir dan membuat plot laporan
python3 analisis.pyruang
Lab A 3
Lab B 2
Ruang Arsip 2
Name: hilang, dtype: int64
ruang suhu_rata suhu_std jumlah_bacaan
0 Lab A 23.72 1.28 37
1 Lab B 23.87 1.50 39
2 Ruang Arsip 24.30 1.72 20
status_sensor kalibrasi normal rusak
ruang
Lab A 3 33 1
Lab B 5 32 2
Ruang Arsip 3 17 0
Pertanyaan a: suhu paling tidak stabil di Ruang Arsip, simpangan baku 1.72 derajat Celsius
Pertanyaan b: 7 bacaan suhu hilang, rinciannya pada tabel pertama
Pertanyaan c: bacaan rusak terbanyak di Lab B, sebanyak 2 bacaan
tersimpan suhu-ruang.svgMembaca keluaran sebagai jawaban tiga pertanyaan#
Keluaran analisis.py tersusun agar setiap bagian menjawab satu pertanyaan lingkup secara langsung. Tabel pertama menjawab pertanyaan b, yaitu jumlah bacaan suhu hilang per ruang sebelum pengisian, dengan rincian tiga bacaan di Lab A, dua di Lab B, dan dua di Ruang Arsip, dengan total tujuh bacaan. Lab A menjadi urutan pertama pemeriksaan kelengkapan log karena kehilangannya paling banyak. Tabel kedua menjawab pertanyaan a, yaitu kestabilan suhu, dan simpangan baku tertinggi berada pada Ruang Arsip sebesar 1.72 derajat Celsius, dibandingkan 1.28 pada Lab A dan 1.50 pada Lab B. Angka itu perlu dibaca bersama kolom jumlah_bacaan, karena simpangan Ruang Arsip dihitung dari 20 bacaan, sehingga kesimpulannya kuat sekaligus menyisakan pertanyaan lanjutan tentang sampel yang lebih kecil.
Tabel ketiga menjawab pertanyaan c melalui tabulasi silang. Bacaan berstatus rusak terbanyak berada di Lab B sebanyak dua bacaan, sedangkan Ruang Arsip tidak memiliki satu pun, sehingga prioritas perbaikan sensor jatuh pada Lab B. Tiga baris terakhir keluaran mencetak kesimpulan tersebut sebagai teks siap kutip, dan namanya diambil dari hasil perhitungan melalui idxmax, bukan diketik manual, sehingga kesimpulan tetap benar apabila data berubah.
Plot batang rata-rata suhu per ruang#
Bagian akhir skrip menggambar satu plot batang rata-rata suhu per ruang dan menyimpannya sebagai suhu-ruang.svg pada folder kerja. Plotnya dibuat dengan plot.bar dari tabel ringkasan, yaitu plot bawaan pandas yang dibahas pada topik Plot Bawaan pandas, dengan matplotlib berjalan pada backend Agg sehingga tidak membutuhkan layar. Metode savefig menyimpan berkasnya, sedangkan plt.close menutup figur agar memori tidak menumpuk ketika skrip dijalankan berulang.
Gambar yang dihasilkan menampilkan tiga batang dengan tinggi 23.72, 23.87, dan 24.30 derajat Celsius. Selisih antar-ruang jauh lebih kecil daripada simpangan baku masing-masing ruang, sehingga pesan utama laporan menyangkut kestabilan suhu, bukan tingkat suhu rata-ratanya. Pemilihan plot pun mengikuti pertanyaan lingkup, yaitu satu ukuran ringkas per ruang, bukan deret waktu penuh yang justru menyulitkan pembaca laporan.
Berkas suhu-ruang.svg berformat vektor, sehingga tetap tajam ketika diperbesar pada dokumen laporan. Pembaca yang membutuhkan gambar lain cukup mengubah kolom pada plot.bar, misalnya suhu_std untuk membandingkan kestabilan antar-ruang. Pola penyimpanannya sama untuk plot apa pun, karena backend Agg tidak bergantung pada layar.
Keterampilan yang berhimpun pada proyek#
Ketiga skrip proyek merangkai mekanisme yang dibahas pada seluruh modul jalur ini. Pembacaan dan penulisan berkas CSV berasal dari modul Membaca dan Menulis Data, sedangkan deteksi NaN, duplikat, dan pengisiannya berasal dari modul Pembersihan. Pengelompokan dengan groupby dan transform berasal dari modul GroupBy, sementara penggabungan dengan merge beserta validate berasal dari modul Penggabungan Data. Tabulasi silang berasal dari modul Pengubahan Bentuk, dan plot batang berasal dari modul Visualisasi dan Performa. Seleksi dan deret waktu ikut bekerja pada kolom waktu dan penyaringan yang menyertainya.
Susunan tersebut menunjukkan bentuk akhir sebuah pekerjaan data, yaitu beberapa skrip kecil yang masing-masing dapat dijalankan ulang dan diperiksa tahap demi tahap. Skrip yang sama dapat diperluas dengan pertanyaan baru, misalnya kelembapan per ruang, cukup dengan menambahkan satu agregasi lagi tanpa mengubah tahap lainnya. Kebiasaan kerja yang menyertai mekanisme itu sama pentingnya dengan kodenya, yaitu setiap tahap diberi pembanding angka, setiap penggabungan diberi validasi bentuk, dan setiap hasil disimpan sebagai berkas yang dapat diperiksa ulang. Susunan semacam ini membuat proyek dapat dilanjutkan tanpa menebak langkah yang sudah dilewati.
Ringkasan#
analisis.pyberdiri sendiri karena generator yang sama dipanggil ulang, sehingga angka analisis identik denganpipeline.pytanpa bergantung pada berkas antar-topik.- Setiap tabel keluaran menjawab satu pertanyaan lingkup, dan kesimpulannya dicetak dengan nama ruang yang diambil dari
idxmax, bukan diketik manual. - Plot batang rata-rata suhu disimpan sebagai
suhu-ruang.svgmelalui backend Agg,savefig, danplt.close, tanpa menampilkan jendela plot.
Referensi#
- Chart visualization — pandas documentation — Panduan plot Series dan DataFrame melalui matplotlib, termasuk diagram batang yang dipakai pada laporan proyek ini.