πŸ“˜ Modul Analisis Hidrologi

Visualisasi Data Hujan
dengan R & ggplot2

Studi kasus: Sta. Hujan Cemara, Bandung Β· Periode 2000–2025

60 menit belajar 9.487 data harian Tingkat: Dasar–Menengah
πŸ”΅ R β‰₯ 4.0 πŸ“¦ ggplot2 πŸ”§ tidyverse
1

Pendahuluan & Tujuan Pembelajaran

0
Data harian Sta. Cemara
0
Tahun pengamatan
0
Jenis visualisasi dibahas
0
mm Β· Bulan terbasa (Nov)
Mengapa R & ggplot2 untuk data hujan?

Microsoft Excel cukup untuk rekap sederhana, tetapi untuk visualisasi yang konsisten, reproducible, dan publication-quality β€” R dengan ggplot2 jauh lebih unggul. Satu script R bisa menghasilkan puluhan chart sekaligus, dengan format, warna, dan label yang seragam secara otomatis.

Keunggulan ggplot2

Berbasis Grammar of Graphics β€” setiap chart dibangun dari lapisan (layer) yang konsisten. Mudah dimodifikasi, mudah direproduksi, dan menghasilkan output PNG/SVG/PDF berkualitas tinggi.

Cocok untuk hidrologi

Mendukung time series panjang, heatmap bulan Γ— tahun, multi-panel per stasiun, dan integrasi langsung dengan analisis statistik seperti regresi, uji tren, dan analisis frekuensi.

Setelah mempelajari modul ini, kamu dapat:
βœ“
Menyiapkan lingkungan R + ggplot2 untuk analisis data hujan
Instalasi package, struktur data frame, dan import file Excel/CSV.
βœ“
Memahami Grammar of Graphics sebagai fondasi ggplot2
Konsep aes(), geom_*, stat_*, dan theme yang membangun setiap chart.
βœ“
Membuat bar chart, line chart, dan heatmap data hujan
Dengan data nyata Sta. Cemara Bandung, lengkap label, warna, dan anotasi.
βœ“
Menggabungkan beberapa chart dalam satu layout (patchwork)
Membuat panel figure siap laporan atau publikasi ilmiah.
ℹ️Modul ini menggunakan data yang sama dengan modul Excel sebelumnya: Sta. Hujan Cemara, Bandung 2000–2025 (BMKG Bandung). Kamu bisa langsung menggunakan file sta_hujan_cemara_bandung_2000_2025.xlsx yang sudah disiapkan.
2

Setup & Instalasi Package

tidyverse
Meta-package: ggplot2, dplyr, tidyr, readr, lubridate, dll β€” semua yang dibutuhkan dalam satu instalasi.
readxl
Import file .xlsx dan .xls langsung ke R tanpa perlu konversi ke CSV terlebih dahulu.
scales
Format sumbu chart secara otomatis: ribuan, persen, tanggal, dan unit kustom seperti "mm".
patchwork
Menggabungkan beberapa objek ggplot menjadi satu layout multi-panel dengan operator + dan /.
R Β· Instalasi Package
# Instalasi (jalankan sekali saja)
install.packages("tidyverse")  # termasuk ggplot2, dplyr, lubridate
install.packages("readxl")     # baca file Excel
install.packages("scales")     # format sumbu
install.packages("patchwork")  # multi-panel layout

# Load package di setiap sesi
library(tidyverse)
library(readxl)
library(scales)
library(patchwork)
πŸ’‘Gunakan RStudio sebagai IDE β€” tersedia gratis di posit.co. Pastikan versi R β‰₯ 4.0 agar semua fitur tidyverse berjalan optimal. Cek versi dengan R.version di console.
3

Import & Persiapan Data

Sebelum membuat chart, data harian perlu diimport dan dibersihkan β€” menghapus kode 8888 (data hilang) dan membuat kolom turunan seperti Tahun, Bulan, dan flag hari hujan.

R Β· Import & Bersihkan Data
library(tidyverse)
library(readxl)

# ── 1. Import sheet data_harian ─────────────────────────────
df_raw <- read_excel(
  "sta_hujan_cemara_bandung_2000_2025.xlsx",
  sheet = "data_harian"
)

# ── 2. Bersihkan & buat kolom turunan ───────────────────────
df <- df_raw |>
  rename(
    tanggal  = Tanggal,
    rr_raw   = RR,
    rr_mm    = `Curah_hujan (mm)`
  ) |>
  mutate(
    rr_mm   = if_else(rr_raw == 8888, NA_real_, rr_raw),  # ganti 8888 β†’ NA
    tahun   = year(tanggal),
    bulan   = month(tanggal, label = TRUE, abbr = TRUE),
    bln_num = month(tanggal),
    hujan   = if_else(rr_mm > 0, 1L, 0L, missing = 0L)  # flag hari hujan
  )

# ── 3. Cek hasil ────────────────────────────────────────────
glimpse(df)
summary(df$rr_mm)
Contoh struktur df setelah import (5 baris pertama):
tanggalrr_rawrr_mmtahunbulanbln_numhujan
2000-01-012.82.82000Jan11
2000-01-02002000Jan10
2000-01-031.81.82000Jan11
2000-01-198888NA2000Jan10
2000-01-202.02.02000Jan11
R Β· Buat Tabel Rekap (dipakai semua chart)
# ── Rekap bulanan: rata-rata curah hujan per bulan (26 tahun) ──
df_bulanan <- df |>
  group_by(tahun, bln_num, bulan) |>
  summarise(
    total_mm   = sum(rr_mm, na.rm = TRUE),
    maks_mm    = max(rr_mm, na.rm = TRUE),
    hari_hujan = sum(hujan, na.rm = TRUE),
    .groups    = "drop"
  )

# ── Rekap tahunan ────────────────────────────────────────────
df_tahunan <- df_bulanan |>
  group_by(tahun) |>
  summarise(
    total_mm   = sum(total_mm),
    maks_mm    = max(maks_mm),
    hari_hujan = sum(hari_hujan)
  )

# ── Rata-rata bulanan (lintas tahun) ─────────────────────────
df_avg_bln <- df_bulanan |>
  group_by(bln_num, bulan) |>
  summarise(avg_mm = mean(total_mm), .groups = "drop")
ℹ️Operator pipe |> (native pipe R 4.1+) atau %>% (magrittr) fungsinya sama β€” meneruskan hasil fungsi sebelumnya sebagai argumen pertama fungsi berikutnya. Keduanya bisa dipakai secara bergantian.
4

Grammar of Graphics β€” Fondasi ggplot2

Setiap chart ggplot2 dibangun dari komponen yang sama β€” seperti tata bahasa (grammar). Memahami ini membuat kamu bisa memodifikasi chart apa pun dengan mudah.

Struktur dasar ggplot2
R Β· Template Universal ggplot2
ggplot(data = <DATA>,              # 1. Data frame sumber
       aes(x = <X>, y = <Y>,          # 2. Aesthetic mapping
           fill = <VAR>, color = <VAR>)) +
  <GEOM_FUNCTION>() +               # 3. Geometri (bar, line, tile...)
  <SCALE_FUNCTION>() +              # 4. Skala sumbu & warna
  <COORD_FUNCTION>() +              # 5. Sistem koordinat
  <FACET_FUNCTION>() +              # 6. Panel / facet (opsional)
  labs(title = "...", x = "...",    # 7. Label
       y = "...", caption = "...") +
  <THEME_FUNCTION>()                # 8. Tema (tampilan)
Klik geom untuk melihat penggunaan dalam analisis data hujan:
πŸ“Š
geom_col()
Bar chart absolut
πŸ“ˆ
geom_line()
Tren deret waktu
🟦
geom_tile()
Heatmap grid
πŸ”΅
geom_point()
Scatter plot
πŸ“‰
geom_area()
Area bawah kurva
πŸ“
geom_hline()
Garis referensi
5

Bar Chart β€” Curah Hujan Bulanan

Bar chart rata-rata bulanan adalah visualisasi paling umum dalam laporan hidrologi. Berikut versi bertahap β€” dari yang paling dasar hingga versi siap laporan.

R Β· Bar Chart Dasar
# ── Versi dasar: 3 baris ────────────────────────────────────
ggplot(df_avg_bln, aes(x = bulan, y = avg_mm)) +
  geom_col(fill = "#378add") +
  labs(title = "Rata-rata Curah Hujan Bulanan",
       y = "mm", x = NULL)
R Β· Bar Chart Siap Laporan (lengkap)
# ── Warna per kategori musim ─────────────────────────────────
warna_bln <- c(
  "Jan"="#185fa5", "Feb"="#185fa5", "Mar"="#185fa5",
  "Apr"="#378add", "Mei"="#378add",
  "Jun"="#85b7eb", "Jul"="#85b7eb", "Agt"="#b5d4f4", "Sep"="#85b7eb",
  "Okt"="#378add", "Nov"="#185fa5", "Des"="#185fa5"
)

p_bulanan <- ggplot(df_avg_bln, aes(x = bulan, y = avg_mm, fill = bulan)) +

  # β‘  Bar utama
  geom_col(show.legend = FALSE, width = 0.75) +

  # β‘‘ Garis rata-rata tahunan
  geom_hline(yintercept = 184, linetype = "dashed",
             color = "#ef9f27", linewidth = 0.8) +

  # β‘’ Label di atas bar
  geom_text(aes(label = round(avg_mm, 0)),
            vjust = -0.4, size = 3, color = "#495057") +

  # β‘£ Anotasi garis rata-rata
  annotate("text", x = 11.5, y = 192,
           label = "Rata-rata 184 mm",
           size = 3, color = "#ef9f27", fontface = "bold") +

  # β‘€ Warna & skala
  scale_fill_manual(values = warna_bln) +
  scale_y_continuous(expand = expansion(mult = c(0, 0.12)),
                     labels = label_number(suffix = " mm")) +

  # β‘₯ Label
  labs(
    title   = "Rata-rata Curah Hujan Bulanan",
    subtitle= "Sta. Hujan Cemara, Bandung Β· 2000–2025",
    x = NULL, y = "Curah Hujan (mm)",
    caption = "Sumber: BMKG Bandung"
  ) +

  # ⑦ Tema
  theme_minimal(base_size = 12) +
  theme(
    plot.title    = element_text(face = "bold"),
    plot.subtitle = element_text(color = "grey50", size = 10),
    panel.grid.major.x = element_blank()
  )

print(p_bulanan)
πŸ“Š Output: p_bulanan
Rata-rata Curah Hujan Bulanan
Sta. Hujan Cemara, Bandung Β· 2000–2025  |  Sumber: BMKG Bandung
Musim Hujan (>200 mm)
Peralihan
Kemarau
 Rata-rata (184 mm)
6

Line Chart β€” Curah Hujan Tahunan

R Β· Line & Bar Chart Tahunan
# ── Tambahkan kolom kategori tahun ──────────────────────────
df_tahunan <- df_tahunan |>
  mutate(
    kategori = case_when(
      total_mm > 3000 ~ "Ekstrem Basah",
      total_mm < 1800 ~ "Kering",
      .default        = "Normal"
    )
  )

# ── Bar chart tahunan ────────────────────────────────────────
p_tahunan <- ggplot(df_tahunan, aes(x = tahun, y = total_mm, fill = kategori)) +

  geom_col(width = 0.7) +
  geom_hline(yintercept = 2215, linetype = "dashed",
             color = "#1d9e75", linewidth = 0.9) +

  # Label hanya untuk tahun ekstrem
  geom_text(
    data = ~filter(.x, kategori != "Normal"),
    aes(label = comma(total_mm)),
    vjust = -0.4, size = 2.8, fontface = "bold"
  ) +

  scale_fill_manual(
    values = c("Ekstrem Basah" = "#a32d2d",
               "Kering"        = "#ef9f27",
               "Normal"        = "#378add")
  ) +
  scale_y_continuous(labels = comma,
                     expand = expansion(mult = c(0.02, 0.12))) +
  scale_x_continuous(breaks = seq(2000, 2025, 5)) +
  labs(
    title    = "Curah Hujan Tahunan 2000–2025",
    subtitle = "Sta. Hujan Cemara, Bandung | Garis hijau = rata-rata 2.215 mm",
    x = NULL, y = "Curah Hujan (mm)",
    fill = "Kategori", caption = "Sumber: BMKG Bandung"
  ) +
  theme_minimal(base_size = 12) +
  theme(panel.grid.major.x = element_blank(),
        plot.title = element_text(face = "bold"))

print(p_tahunan)
πŸ“Š Output: p_tahunan
Curah Hujan Tahunan 2000–2025
Sta. Hujan Cemara, Bandung | Garis hijau = rata-rata 2.215 mm
Ekstrem Basah
Normal
Kering
 Rata-rata (2.215 mm)
πŸ”¬Tahun 2010 (3.694 mm) dan 2016 (3.406 mm) adalah outlier ekstrem yang berkorelasi dengan fenomena La NiΓ±a. Sebaliknya, tahun 2006 (1.702 mm) dan 2023 (1.738 mm) merupakan tahun kering terkait El NiΓ±o. Pola ini terlihat jelas dari warna merah vs oranye pada chart.
7

Heatmap β€” Pola Bulan Γ— Tahun

Heatmap dengan geom_tile() adalah cara paling efektif menampilkan data 26 tahun Γ— 12 bulan sekaligus dalam satu chart. Pola El NiΓ±o/La NiΓ±a, musim kemarau, dan bulan basah ekstrem langsung terlihat.

R Β· Heatmap geom_tile()
# ── Heatmap curah hujan bulanan Γ— tahunan ───────────────────
p_heatmap <- ggplot(df_bulanan,
  aes(x = factor(bln_num), y = factor(tahun), fill = total_mm)) +

  # β‘  Kotak warna
  geom_tile(color = "white", linewidth = 0.3) +

  # β‘‘ Label nilai di tiap sel
  geom_text(aes(label = round(total_mm, 0)),
            size = 2.5, color = ifelse(df_bulanan$total_mm > 300, "white", "#333")) +

  # β‘’ Skala warna: putih (kering) β†’ biru tua (basah)
  scale_fill_gradient2(
    low      = "#f0f7ff",
    mid      = "#378add",
    high     = "#0a2540",
    midpoint = 200,
    name     = "mm"
  ) +

  # β‘£ Label sumbu X: nama bulan
  scale_x_discrete(labels = c("Jan","Feb","Mar","Apr","Mei","Jun",
                                "Jul","Agt","Sep","Okt","Nov","Des")) +

  labs(
    title    = "Heatmap Curah Hujan Bulanan (mm)",
    subtitle = "Sta. Hujan Cemara, Bandung Β· 2000–2025",
    x = "Bulan", y = "Tahun",
    caption  = "Sumber: BMKG Bandung"
  ) +
  theme_minimal(base_size = 11) +
  theme(
    plot.title    = element_text(face = "bold"),
    axis.text.y   = element_text(size = 8),
    panel.grid    = element_blank(),
    legend.position = "right"
  )

print(p_heatmap)
πŸ“Š Output: p_heatmap β€” Heatmap Curah Hujan Bulanan (mm)
Skala warna:
0 mm β†’ kering  |  >400 mm β†’ sangat basah
πŸ‘οΈPerhatikan baris tahun 2010 dan 2016 β€” hampir seluruh kolomnya biru gelap (La NiΓ±a). Sebaliknya tahun 2015 memiliki banyak sel biru muda di bulan Jun–Sep (El NiΓ±o kemarau panjang). Informasi ini tidak mungkin terlihat dari tabel angka biasa.
8

Multi-panel dengan patchwork

Package patchwork memungkinkan penggabungan beberapa objek ggplot menjadi satu figure layout. Cocok untuk laporan AMDAL, presentasi, atau publikasi ilmiah.

R Β· Multi-panel dengan patchwork
library(patchwork)

# ── Chart hari hujan tahunan ─────────────────────────────────
p_harihujan <- ggplot(df_tahunan, aes(x = tahun, y = hari_hujan)) +
  geom_line(color = "#639922", linewidth = 1.1) +
  geom_point(color = "#639922", size = 2.5, fill = "white", shape = 21) +
  geom_hline(yintercept = mean(df_tahunan$hari_hujan),
             linetype = "dashed", color = "#639922", alpha = 0.5) +
  scale_x_continuous(breaks = seq(2000, 2025, 5)) +
  labs(title = "Hari Hujan per Tahun", x = NULL, y = "Hari") +
  theme_minimal(base_size = 11)

# ── Gabungkan: tahunan (atas) / hari hujan (bawah) ──────────
figure_final <- p_tahunan / p_harihujan +
  plot_annotation(
    title   = "Ringkasan Hidrologi Sta. Hujan Cemara, Bandung",
    subtitle= "Periode Pengamatan 2000–2025",
    caption = "Sumber: BMKG Bandung Β· Analisis: irpanchumaedi.com",
    theme   = theme(plot.title = element_text(face = "bold", size = 14))
  )

print(figure_final)
πŸ“Š Output: figure_final β€” Multi-panel patchwork
Ringkasan Hidrologi Sta. Hujan Cemara, Bandung
Periode Pengamatan 2000–2025
Sumber: BMKG Bandung Β· Analisis: irpanchumaedi.com
Operator patchwork yang wajib diketahui
OperatorFungsiContoh
p1 + p2Susun sejajar (side by side)2 chart dalam 1 baris
p1 / p2Susun atas-bawah (stacked)2 chart dalam 1 kolom
(p1 + p2) / p32 di atas, 1 di bawahLayout 3-panel
p1 + plot_spacer()Tambah ruang kosongPadding antar panel
plot_layout(ncol=2)Atur jumlah kolom4 chart β†’ 2Γ—2 grid
9

Ekspor Chart & Tips Profesional

R Β· Ekspor dengan ggsave()
# ── PNG resolusi tinggi (untuk laporan/presentasi) ───────────
ggsave(
  filename = "curah_hujan_bulanan_cemara.png",
  plot     = p_bulanan,
  width    = 10,        # lebar dalam inci
  height   = 6,         # tinggi dalam inci
  dpi      = 300,       # resolusi (300 dpi = print quality)
  bg       = "white"    # background putih
)

# ── PDF vektoral (untuk jurnal/laporan teknis) ───────────────
ggsave(
  filename = "heatmap_cemara.pdf",
  plot     = p_heatmap,
  width    = 14, height = 8,
  device   = "pdf"
)

# ── Multi-panel figure ───────────────────────────────────────
ggsave(
  filename = "ringkasan_hidrologi_cemara.png",
  plot     = figure_final,
  width    = 12, height = 9, dpi = 300
)
Tips membuat chart ggplot2 yang profesional:
  • 🎨Gunakan tema yang konsisten. Tetapkan satu tema di seluruh script: theme_set(theme_minimal(base_size = 12)) di awal file. Semua chart akan otomatis menggunakan tema yang sama.
  • πŸ”€Font untuk laporan teknis. Tambahkan library(showtext) untuk menggunakan Google Fonts seperti Roboto atau Source Sans Pro β€” hasilnya jauh lebih bersih dari font default R.
  • πŸ“Selalu tambahkan unit pada sumbu Y. Gunakan scale_y_continuous(labels = label_number(suffix = " mm")) β€” jangan hanya tulis "mm" di nama sumbu karena tidak terlihat di presentasi.
  • 🏷️Caption untuk sumber data. Selalu isi caption di labs() dengan sumber data dan tahun analisis. Ini wajib untuk laporan AMDAL dan dokumen teknis.
  • πŸ”Buat fungsi R untuk chart yang berulang. Jika analisis dilakukan untuk banyak stasiun, buat fungsi plot_curah_hujan(data, nama_sta) agar tidak copy-paste kode yang sama berkali-kali.
  • πŸ“Pisahkan script per tujuan. Gunakan struktur: 01_import.R, 02_rekap.R, 03_visualisasi.R, 04_ekspor.R. Lebih mudah di-maintain dan di-debug.
Rangkuman alur kerja lengkap di R
β‘  read_excel() β†’ β‘‘ mutate() + filter() β†’ β‘’ group_by() + summarise() β†’ β‘£ ggplot() + geom_*() β†’ β‘€ theme() + labs() β†’ β‘₯ ggsave()
Kuasai dasar ggplot2 dulu βœ…

Setelah ini, lanjut ke bagian berikutnya β€” visualisasi yang tidak mungkin dibuat di Excel. πŸ‘‡

πŸ”₯

Yang Tidak Bisa Dilakukan di Excel

Mengapa harus belajar R?
Learning curve lebih tinggi = ekspektasi output juga harus lebih tinggi.

Bar chart dan line chart bisa dibuat di Excel dalam 30 detik. Kalau ggplot2 hanya menghasilkan hal yang sama, tidak ada alasan kuat untuk pindah. Bagian ini membuktikan bahwa R mampu menghasilkan visualisasi yang secara teknis tidak mungkin dibuat di Excel β€” bukan sekadar "lebih cantik".

❌ Excel β€” Terbatas
  • πŸ”˜ Bar, line, pie, scatter β€” itu saja
  • πŸ”˜ Boxplot tidak proper (tanpa outlier)
  • πŸ”˜ Satu chart = satu proses manual
  • πŸ”˜ Tidak bisa confidence interval
  • πŸ”˜ Tidak bisa distribusi probabilitas
  • πŸ”˜ Copy-paste untuk tiap stasiun
βœ… ggplot2 β€” Tidak Terbatas
  • 🟒 Boxplot lengkap dengan outlier
  • 🟒 26 chart sekaligus (facet_wrap)
  • 🟒 Garis tren + confidence interval
  • 🟒 Ridgeline β€” distribusi per bulan
  • 🟒 1 fungsi β†’ semua stasiun
  • 🟒 Output PDF vektoral siap jurnal
⚑Empat visualisasi berikut adalah argumen terkuat mengapa hidrologist perlu belajar R. Semuanya menggunakan data yang sama: Sta. Cemara Bandung 2000–2025.
10

Boxplot β€” Distribusi Harian per Bulan

❌ Mengapa Excel tidak cukup di sini?

Bar chart rata-rata bulanan menyembunyikan informasi penting: seberapa besar variasi hariannya? Apakah November selalu >200mm atau hanya rata-ratanya saja? Boxplot menjawab semua ini sekaligus β€” median, sebaran, dan outlier ekstrem dalam satu gambar.

R Β· Boxplot Distribusi Harian per Bulan
# ── Boxplot curah hujan harian per bulan (hanya hari hujan) ─
p_boxplot <- df |>
  filter(rr_mm > 0) |>                       # hanya hari hujan

  ggplot(aes(x = bulan, y = rr_mm, fill = bulan)) +

  # β‘  Boxplot utama
  geom_boxplot(
    show.legend  = FALSE,
    outlier.shape  = 21,
    outlier.fill   = "#e24b4a",
    outlier.color  = "white",
    outlier.size   = 1.8,
    outlier.alpha  = 0.7,
    width          = 0.6
  ) +

  # β‘‘ Titik rata-rata (diamond)
  stat_summary(fun = mean, geom = "point",
               shape = 23, size = 3,
               fill = "#ef9f27", color = "white") +

  # β‘’ Garis threshold hujan lebat (β‰₯50mm/hari, SNI)
  geom_hline(yintercept = 50, linetype = "dashed",
             color = "#e24b4a", linewidth = 0.7) +
  annotate("text", x = 11.6, y = 53,
           label = "β‰₯50 mm = Hujan Lebat (BMG)",
           size = 3, color = "#e24b4a") +

  scale_fill_manual(values = setNames(
    colorRampPalette(c("#b5d4f4", "#185fa5"))(12),
    levels(df$bulan)
  )) +
  scale_y_continuous(labels = label_number(suffix = " mm")) +
  labs(
    title    = "Distribusi Curah Hujan Harian per Bulan",
    subtitle = "Sta. Cemara, Bandung 2000–2025 | β—† = rata-rata | ● merah = outlier ekstrem",
    x = NULL, y = "Curah Hujan (mm/hari)",
    caption  = "Hanya hari dengan curah hujan > 0 mm | Sumber: BMKG Bandung"
  ) +
  theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold"),
        panel.grid.major.x = element_blank())

print(p_boxplot)
πŸ“Š Output: p_boxplot β€” Informasi yang tidak mungkin ada di bar chart Excel
Distribusi Curah Hujan Harian per Bulan
Sta. Cemara, Bandung 2000–2025 Β· β—† = rata-rata Β· ● merah = outlier ekstrem
Box: IQR (25%–75% data)
β—† Rata-rata
Outlier ekstrem
 β‰₯50mm (Hujan Lebat)
πŸ’‘Perhatikan bahwa median November tidak setinggi rata-ratanya β€” artinya ada beberapa hari hujan sangat lebat yang menarik rata-rata ke atas. Bar chart Excel menyembunyikan fakta ini. Boxplot mengungkapnya.
11

Facet Wrap β€” 26 Chart Sekaligus

❌ Di Excel: 26 chart = 26 jam kerja manual

Untuk membuat chart bulanan per tahun di Excel, kamu harus membuat sheet baru, memilih range, insert chart, format, beri judul β€” dan diulang 26 kali. Di R, satu baris facet_wrap(~ tahun) menghasilkan semuanya dalam hitungan detik, dengan format yang 100% konsisten.

R Β· facet_wrap() β€” 26 chart sekaligus
# ── 26 mini chart bulanan β€” satu baris facet_wrap ───────────
p_facet <- ggplot(df_bulanan,
  aes(x = bln_num, y = total_mm, fill = total_mm)) +

  geom_col(show.legend = FALSE, width = 0.85) +

  # ← INI YANG TIDAK BISA DILAKUKAN DI EXCEL
  facet_wrap(~ tahun, ncol = 6) +

  scale_fill_gradient(low = "#b5d4f4", high = "#0a2540") +
  scale_x_continuous(breaks = c(1,6,12),
                     labels = c("Jan","Jun","Des")) +
  scale_y_continuous(labels = label_number(suffix="mm", scale=0.001, accuracy=0.1)) +
  labs(
    title    = "Curah Hujan Bulanan per Tahun β€” Sta. Cemara Bandung",
    subtitle = "26 chart sekaligus | Warna lebih gelap = curah hujan lebih tinggi",
    x = NULL, y = NULL,
    caption  = "Sumber: BMKG Bandung"
  ) +
  theme_minimal(base_size = 9) +
  theme(
    strip.text       = element_text(face = "bold", size = 8),
    panel.grid.minor = element_blank(),
    plot.title       = element_text(face = "bold")
  )

# Simpan ukuran besar agar semua panel terbaca
ggsave("facet_bulanan_cemara.png", p_facet,
       width = 16, height = 12, dpi = 300)
πŸ“Š Output: p_facet β€” 26 chart, satu perintah, format 100% konsisten
Curah Hujan Bulanan per Tahun β€” Sta. Cemara Bandung
26 chart sekaligus Β· Warna lebih gelap = curah hujan lebih tinggi
πŸš€Dengan Excel: Β±4 jam untuk 26 chart (buat chart, format, judul, copy, paste β€” diulang 26Γ—). Dengan R: Β±10 detik render + ggsave(). Untuk 50 stasiun: Excel butuh seminggu, R butuh 10 menit tambahan.
12

Tren Jangka Panjang + Confidence Interval

❌ Di Excel: trendline ada, tapi confidence interval tidak bisa

Excel bisa menambahkan garis tren linear, tapi tidak bisa menampilkan uncertainty band (pita kepercayaan). Padahal dalam analisis perubahan iklim, CI adalah informasi kritis β€” menunjukkan seberapa yakin kita dengan arah tren tersebut.

R Β· Tren + Confidence Interval 95%
# ── Tren curah hujan tahunan + CI 95% ───────────────────────
p_trend <- ggplot(df_tahunan, aes(x = tahun, y = total_mm)) +

  # β‘  Bar abu-abu sebagai latar
  geom_col(fill = "#85b7eb", alpha = 0.5, width = 0.7) +

  # β‘‘ Garis tren + pita CI 95% ← tidak bisa di Excel
  geom_smooth(
    method    = "lm",          # linear model
    color     = "#e24b4a",
    fill      = "#e24b4a",
    alpha     = 0.15,           # transparansi pita CI
    linewidth = 1.2,
    se        = TRUE            # tampilkan CI
  ) +

  # β‘’ Hitung dan tampilkan nilai tren
  annotate("text",
    x = 2002, y = 3500,
    label = paste("Tren:",
      round(coef(lm(total_mm ~ tahun, df_tahunan))[2], 1),
      "mm/tahun"),
    size = 4, color = "#e24b4a", fontface = "bold", hjust = 0
  ) +

  scale_x_continuous(breaks = seq(2000, 2025, 5)) +
  scale_y_continuous(labels = comma,
                     limits = c(0, 4200)) +
  labs(
    title    = "Tren Curah Hujan Tahunan 2000–2025",
    subtitle = "Pita merah = Confidence Interval 95% | Area pita = zona ketidakpastian",
    x = NULL, y = "Curah Hujan Tahunan (mm)",
    caption  = "Metode: Linear Model (lm) | Sumber: BMKG Bandung"
  ) +
  theme_minimal(base_size = 12) +
  theme(plot.title = element_text(face = "bold"))

print(p_trend)
πŸ“Š Output: p_trend β€” Tren + pita CI 95%
Tren Curah Hujan Tahunan 2000–2025
Pita merah = Confidence Interval 95% Β· Area pita = zona ketidakpastian tren
Curah hujan tahunan
Garis tren (lm)
Confidence Interval 95%
πŸ“Tren positif (naik) di Sta. Cemara belum tentu signifikan secara statistik β€” pita CI yang lebar menunjukkan ketidakpastian tinggi. Untuk uji signifikansi formal, gunakan summary(lm(total_mm ~ tahun, df_tahunan)) dan periksa nilai p-value.
13

Ridgeline Chart β€” Distribusi Intensitas per Bulan

❌ Di Excel: tidak ada padanannya, sama sekali

Ridgeline chart (atau joy plot) menampilkan kurva distribusi probabilitas curah hujan harian untuk setiap bulan secara tumpang tindih. Ini bukan sekadar "lebih cantik" β€” ini menyampaikan informasi yang tidak bisa ditampilkan dalam bentuk tabel atau bar chart mana pun.

R Β· Ridgeline Chart (ggridges)
library(ggridges)   # install.packages("ggridges")
library(forcats)   # sudah termasuk dalam tidyverse

# ── Ridgeline: distribusi intensitas hujan harian per bulan ─
p_ridge <- df |>
  filter(rr_mm > 0) |>
  mutate(bulan = fct_rev(bulan)) |>   # Jan di atas

  ggplot(aes(x = rr_mm, y = bulan,
             fill = after_stat(x))) +   # warna = intensitas

  # β‘  Kurva distribusi bergradien
  geom_density_ridges_gradient(
    scale          = 2.5,    # tingkat tumpang tindih
    rel_min_height = 0.01,
    color          = "white",
    linewidth      = 0.4
  ) +

  # β‘‘ Gradien warna: biru muda (ringan) β†’ biru tua (lebat)
  scale_fill_gradientn(
    colors = c("#e6f1fb", "#378add", "#0a2540", "#e24b4a"),
    values = c(0, 0.3, 0.7, 1),
    guide  = "none"
  ) +

  # β‘’ Garis referensi: 50mm (hujan lebat)
  geom_vline(xintercept = 50, linetype = "dashed",
             color = "#ef9f27", linewidth = 0.8) +

  scale_x_continuous(
    limits = c(0, 150),
    labels = label_number(suffix = " mm")
  ) +
  labs(
    title    = "Distribusi Intensitas Hujan Harian per Bulan",
    subtitle = "Sta. Cemara, Bandung 2000–2025 | Garis oranye = 50mm (Hujan Lebat)",
    x = "Intensitas (mm/hari)", y = NULL,
    caption  = "Hanya hari hujan (RR > 0) | Sumber: BMKG Bandung"
  ) +
  theme_ridges(grid = FALSE) +
  theme(plot.title = element_text(face = "bold"))

print(p_ridge)
πŸ“Š Output: p_ridge β€” Visualisasi yang tidak ada padanannya di Excel
Distribusi Intensitas Hujan Harian per Bulan
Sta. Cemara, Bandung 2000–2025 Β· Garis oranye = 50 mm/hari (threshold Hujan Lebat BMG)
πŸ‘οΈPerhatikan "ekor panjang" di bulan November dan Februari β€” kurva melebar jauh ke kanan (>100 mm/hari). Ini menunjukkan bahwa bulan-bulan tersebut tidak hanya banyak hujannya, tapi juga punya potensi hujan sangat lebat yang tinggi. Informasi ini kritis untuk desain saluran drainase dan analisis banjir.
14

Otomasi β€” 1 Fungsi untuk Semua Stasiun

❌ Di Excel: 1 stasiun baru = 1 file baru = pekerjaan berulang

Setiap kali ada stasiun baru, proses di Excel harus diulang dari awal: import data, buat pivot, format, buat chart, simpan. Dalam proyek AMDAL yang punya 10–20 stasiun, ini bisa memakan waktu berhari-hari. Di R, kamu tulis fungsi sekali β€” lalu loop untuk semua stasiun.

R Β· Fungsi Reusable + Loop Multi-Stasiun
# ── 1. Buat fungsi yang bisa dipakai ulang ──────────────────
buat_chart_hujan <- function(df, nama_stasiun, warna = "#378add") {

  df_avg <- df |>
    filter(rr_mm != 8888) |>
    group_by(tahun, bln_num) |>
    summarise(total = sum(rr_mm, na.rm = TRUE), .groups = "drop") |>
    group_by(bln_num) |>
    summarise(avg = mean(total))

  ggplot(df_avg, aes(x = bln_num, y = avg)) +
    geom_col(fill = warna, width = 0.75) +
    geom_hline(yintercept = mean(df_avg$avg),
               linetype = "dashed", color = "#ef9f27") +
    scale_x_continuous(breaks = 1:12,
      labels = c("Jan","Feb","Mar","Apr","Mei","Jun",
                 "Jul","Agt","Sep","Okt","Nov","Des")) +
    labs(title = paste("Rata-rata Bulanan β€”", nama_stasiun),
         x = NULL, y = "mm") +
    theme_minimal(base_size = 11) +
    theme(panel.grid.major.x = element_blank())
}

# ── 2. Daftar semua stasiun ──────────────────────────────────
stasiun_list <- tibble(
  nama  = c("Cemara", "Lembang", "Padalarang", "Cimahi",
             "Margahayu", "Baleendah"),
  file  = paste0("data/", c("cemara","lembang","padalarang",
                              "cimahi","margahayu","baleendah"), ".xlsx"),
  warna = c("#185fa5","#388e3c","#ba7517",
             "#7b1fa2","#c62828","#00838f")
)

# ── 3. Loop: baca data + buat + simpan chart ─────────────────
dir.create("output_charts", showWarnings = FALSE)

stasiun_list |>
  pwalk(function(nama, file, warna) {

    df_sta <- read_excel(file, sheet = "data_harian")

    p <- buat_chart_hujan(df_sta, nama, warna)

    ggsave(
      filename = paste0("output_charts/", tolower(nama), ".png"),
      plot     = p,
      width = 10, height = 6, dpi = 300, bg = "white"
    )
    message("βœ“ Selesai: ", nama)
  })

# Output: 6 file PNG tersimpan otomatis di folder output_charts/
πŸ“Š Simulasi output: 6 chart stasiun DAS Citarum β€” format identik, dibuat otomatis
🎯Fungsi ini bisa dikembangkan untuk menghasilkan heatmap, boxplot, dan laporan PDF per stasiun β€” semuanya dengan satu kali pwalk(). Untuk proyek AMDAL dengan 15 stasiun dan 4 jenis chart = 60 file output dalam <2 menit.
πŸŽ“
Learning curve-nya memang tinggi.

Tapi sekarang kamu sudah tahu apa yang menunggu di ujungnya β€” boxplot distribusi, 26 chart sekaligus, confidence interval, ridgeline, dan otomasi penuh.

Excel bisa membuat chart. R bisa membuat analisis.

Ada pertanyaan? Hubungi saya β†’