library (ggplot2)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(sf)
## Linking to GEOS 3.13.1, GDAL 3.11.0, PROJ 9.6.0; sf_use_s2() is TRUE

Membaca shapefile (Provinsi Jawa Tengah)

peta <- st_read("D:/Semester 5/Statistika Lingkungan/33.24_kecamatan.geojson")
## Reading layer `33.24_kecamatan' from data source 
##   `D:\Semester 5\Statistika Lingkungan\33.24_kecamatan.geojson' 
##   using driver `GeoJSON'
## Simple feature collection with 20 features and 4 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XYZ
## Bounding box:  xmin: 109.9227 ymin: -7.201756 xmax: 110.3664 ymax: -6.833059
## z_range:       zmin: 0 zmax: 0
## Geodetic CRS:  WGS 84
peta
## Simple feature collection with 20 features and 4 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XYZ
## Bounding box:  xmin: 109.9227 ymin: -7.201756 xmax: 110.3664 ymax: -6.833059
## z_range:       zmin: 0 zmax: 0
## Geodetic CRS:  WGS 84
## First 10 features:
##    kd_propinsi kd_dati2 kd_kecamatan nm_kecamatan
## 1           33       24          001   Plantungan
## 2           33       24          002   Pageruyung
## 3           33       24          003     Sukorejo
## 4           33       24          004       Patean
## 5           33       24          005    Singorojo
## 6           33       24          006    Limbangan
## 7           33       24          007         Boja
## 8           33       24          008    Kaliwungu
## 9           33       24          009    Brangsong
## 10          33       24          010     Pegandon
##                          geometry
## 1  MULTIPOLYGON Z (((109.9743 ...
## 2  MULTIPOLYGON Z (((110.0187 ...
## 3  MULTIPOLYGON Z (((109.9986 ...
## 4  MULTIPOLYGON Z (((110.0589 ...
## 5  MULTIPOLYGON Z (((110.2228 ...
## 6  MULTIPOLYGON Z (((110.2844 ...
## 7  MULTIPOLYGON Z (((110.2865 ...
## 8  MULTIPOLYGON Z (((110.2845 ...
## 9  MULTIPOLYGON Z (((110.2086 ...
## 10 MULTIPOLYGON Z (((110.1381 ...

Simulasi data Rawan Banjir untuk tiap kecamatan di Kota Kendal

set.seed(123)
data_banjir <- data.frame(
  Kecamatan = peta$nm_kecamatan,
  Lvl_Banjir = sample(1:10, length(peta$nm_kecamatan), replace = TRUE) #1 rendah - 10 sangat rawan
)
data_banjir
##            Kecamatan Lvl_Banjir
## 1         Plantungan          3
## 2         Pageruyung          3
## 3           Sukorejo         10
## 4             Patean          2
## 5          Singorojo          6
## 6          Limbangan          5
## 7               Boja          4
## 8          Kaliwungu          6
## 9          Brangsong          9
## 10          Pegandon         10
## 11             Gemuh          5
## 12            Weleri          3
## 13          Cepiring          9
## 14           Patebon          9
## 15            Kendal          9
## 16          Rowosari          3
## 17          Kangkung          8
## 18        Ringinarum         10
## 19           Ngampel          7
## 20 Kaliwungu Selatan         10

Menggabungkan data dengan peta

peta_data <- left_join(peta, data_banjir, by=c("nm_kecamatan"="Kecamatan"))
peta_data
## Simple feature collection with 20 features and 5 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XYZ
## Bounding box:  xmin: 109.9227 ymin: -7.201756 xmax: 110.3664 ymax: -6.833059
## z_range:       zmin: 0 zmax: 0
## Geodetic CRS:  WGS 84
## First 10 features:
##    kd_propinsi kd_dati2 kd_kecamatan nm_kecamatan Lvl_Banjir
## 1           33       24          001   Plantungan          3
## 2           33       24          002   Pageruyung          3
## 3           33       24          003     Sukorejo         10
## 4           33       24          004       Patean          2
## 5           33       24          005    Singorojo          6
## 6           33       24          006    Limbangan          5
## 7           33       24          007         Boja          4
## 8           33       24          008    Kaliwungu          6
## 9           33       24          009    Brangsong          9
## 10          33       24          010     Pegandon         10
##                          geometry
## 1  MULTIPOLYGON Z (((109.9743 ...
## 2  MULTIPOLYGON Z (((110.0187 ...
## 3  MULTIPOLYGON Z (((109.9986 ...
## 4  MULTIPOLYGON Z (((110.0589 ...
## 5  MULTIPOLYGON Z (((110.2228 ...
## 6  MULTIPOLYGON Z (((110.2844 ...
## 7  MULTIPOLYGON Z (((110.2865 ...
## 8  MULTIPOLYGON Z (((110.2845 ...
## 9  MULTIPOLYGON Z (((110.2086 ...
## 10 MULTIPOLYGON Z (((110.1381 ...

2.Plot Choropleth

ggplot(peta_data) +
geom_sf(aes(fill=Lvl_Banjir), color="white") +
geom_sf_text(aes(label = nm_kecamatan), size = 2, color = "white") +scale_fill_gradient(low="burlywood", high="brown", name="Lvl_Banjir") +theme_minimal() +
labs(title="Choropleth Map Lvl Banjir - Kota Kendal")
## Warning in st_point_on_surface.sfc(sf::st_zm(x)): st_point_on_surface may not
## give correct results for longitude/latitude data

# buat titik density: setiap nilai Lvl_Banjir 
library(sf)
library(ggplot2)
library(dplyr)

# generate titik sesuai Lvl_Banjir
dots <- peta_data %>%
  st_cast("MULTIPOLYGON") %>%
  st_sample(size = .$Lvl_Banjir, type = "random") %>%
  st_sf() %>%
  mutate(value = rep(peta_data$Lvl_Banjir, peta_data$Lvl_Banjir))
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
## Warning in st_poly_sample(x, size = size, ..., type = type, by_polygon =
## by_polygon, : coordinate ranges not computed along great circles; install
## package lwgeom to get rid of this warning
## st_as_s2(): dropping Z and/or M coordinate
## st_as_s2(): dropping Z and/or M coordinate
# mengambil centroid kecamatan untuk label
centroids <- st_centroid(peta_data)
## Warning: st_centroid assumes attributes are constant over geometries
## st_as_s2(): dropping Z and/or M coordinate
# plot dot density + label
ggplot() +
  geom_sf(data = peta_data, fill = "grey90", color = "white") +
  geom_sf(data = dots, aes(color = value), size = 2, alpha = 0.8) +
  geom_text(data = centroids %>% st_drop_geometry(),
            aes(x = st_coordinates(centroids)[,1],
                y = st_coordinates(centroids)[,2],
                label = nm_kecamatan),
            size = 3, color = "black", fontface = "bold") +
  scale_color_gradient(low = "burlywood", high = "brown") +
  theme_minimal() +
  labs(title = "Dot Density Map Level Banjir per Kecamatan",
       color = "Level Banjir")

Interpretasi: Warna gelap → level banjir tinggi. Warna terang → level banjir rendah.

Insight: Hasil menunjukkan bahwa kecamatan di wilayah utara dan tengah seperti Weleri, Rowosari, Kangkung, Kendal, Brangsong, Kaliwungu, dan Kaliwungu Selatan memiliki level banjir lebih tinggi. Sementara itu, kecamatan di bagian selatan seperti Boja, Limbangan, Singorojo, Plantungan, dan Sukorejo cenderung memiliki level banjir lebih rendah. Secara umum, terlihat adanya perbedaan pola antara wilayah utara yang lebih rawan banjir dibanding wilayah selatan.

2.Plot line graph

simulasi perubahan level banjir berdasarkan bulan

library(dplyr)

set.seed(223)

# Bulan (menggunakan angka untuk mempermudah)
bulan <- 1:12

# Buat grid data
data_banjir <- data.frame(Bulan = bulan)

# Simulasi realistis
set.seed(123)
data_banjir <- data_banjir %>%
  rowwise() %>%
  mutate(Level_Banjir = {
    base <- 3
    
    # Musim hujan (Des-Feb, Maret) lebih tinggi
    if (Bulan %in% c(12, 1, 2, 3)) base <- 8
    
    # Peralihan (Apr-Mei, Okt-Nov) sedang
    if (Bulan %in% c(4, 5, 10, 11)) base <- 5
    
    # Musim kemarau (Jun-Sep) rendah
    if (Bulan %in% c(6, 7, 8, 9)) base <- 2
    
    # Variasi acak
    round(rnorm(1, mean = base, sd = 1))
  }) %>%
  ungroup()

print(data_banjir)
## # A tibble: 12 × 2
##    Bulan Level_Banjir
##    <int>        <dbl>
##  1     1            7
##  2     2            8
##  3     3           10
##  4     4            5
##  5     5            5
##  6     6            4
##  7     7            2
##  8     8            1
##  9     9            1
## 10    10            5
## 11    11            6
## 12    12            8
library(ggplot2)

ggplot(data_banjir, aes(x = Bulan, y = Level_Banjir)) +
  geom_line(color = "pink", size = 1.2) +
  geom_point(size = 3, color = "red") +
  theme_minimal() +
  labs(title = "Perubahan Level Banjir per Bulan",
       x = "Bulan", y = "Level Banjir")
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Grafik menunjukkan bahwa level banjir berfluktuasi cukup tajam sepanjang tahun. Pada awal tahun (Januari–Maret), level banjir relatif tinggi dan mencapai puncaknya di bulan Maret dengan nilai tertinggi 10. Setelah itu, terjadi penurunan drastis pada April hingga Juni, dan level banjir mencapai titik terendah di bulan Agustus–September dengan nilai hanya sekitar 1. Mulai bulan Oktober, tren kembali meningkat secara bertahap hingga Desember dengan level mendekati 8.

simulasi Drainase vs. Persentase Wilayah Tergenang

library(ggplot2)
library(dplyr)

set.seed(123)

# Data simulasi
tahun <- 2021:2025
df <- data.frame(
  Tahun = tahun,
  Indeks_Drainase = round(runif(length(tahun), 40, 90),1),   # kualitas drainase
  Persen_Banjir = round(runif(length(tahun), 5, 40),1)       # % wilayah tergenang
)

# Plot Connected Scatter Plot
ggplot(df, aes(x = Indeks_Drainase, y = Persen_Banjir)) +
  geom_path(color = "red", size = 1.2) +           # garis penghubung
  geom_point(color = "red", size = 3) +            # titik tiap tahun
  geom_text(aes(label = Tahun), vjust = -1, size = 3.5) +  # label tahun
  theme_minimal() +
  labs(
    title = "Connected Scatter Plot: Drainase vs. Banjir",
    x = "Indeks Drainase (0-100)",
    y = "Persentase Wilayah Banjir (%)"
  )

Grafik connected scatter plot antara indeks drainase dan persentase wilayah banjir di Kabupaten Kendal menunjukkan bahwa hubungan keduanya tidak selalu linier. Pada tahun 2021, indeks drainase masih relatif rendah dan wilayah terdampak banjir juga kecil. Namun, pada 2022-2023 meskipun terjadi peningkatan kualitas drainase, persentase wilayah yang mengalami banjir justru meningkat. Hal ini menggambarkan bahwa perbaikan infrastruktur drainase belum serta-merta menurunkan banjir, karena faktor lain seperti curah hujan ekstrem, kapasitas saluran yang tidak merata, serta alih fungsi lahan tetap berkontribusi terhadap meningkatnya genangan. Pada 2024–2025 terlihat tren penurunan persentase wilayah banjir seiring dengan semakin tingginya indeks drainase. Fenomena ini mengindikasikan adanya jeda waktu antara pembangunan drainase dengan dampak nyata yang dirasakan di lapangan. Dengan demikian, dapat ditarik kesimpulan bahwa pengendalian banjir di Kendal tidak cukup hanya mengandalkan perbaikan drainase di satu titik atau kecamatan saja, melainkan perlu sistem yang terintegrasi antar wilayah, disertai pengendalian tata ruang dan mitigasi curah hujan ekstrem, agar tren penurunan banjir dapat berkelanjutan.