# install.packages(c("sf","leaflet","RColorBrewer","dplyr","ggplot2","tidyr","ggstream","scales","htmlwidgets"))
library(sf)
## Warning: package 'sf' was built under R version 4.5.1
## Linking to GEOS 3.13.1, GDAL 3.11.0, PROJ 9.6.0; sf_use_s2() is TRUE
library(leaflet)
## Warning: package 'leaflet' was built under R version 4.5.1
library(RColorBrewer)
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(ggplot2)
library(tidyr)
library(ggstream)
## Warning: package 'ggstream' was built under R version 4.5.1
library(scales)
library(htmlwidgets)
## Warning: package 'htmlwidgets' was built under R version 4.5.1
# Baca file GeoJSON
geo_path <- "Pemalang.geojson"
pemalang <- tryCatch(
sf::st_read(geo_path, quiet = TRUE),
error = function(e) stop("Gagal membaca Pemalang.geojson. Pastikan file ada di working directory.")
)
# Tampilkan struktur kolom sederhana
print(head(pemalang))
## Simple feature collection with 1 feature and 12 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 109.1856 ymin: -7.248885 xmax: 109.5992 ymax: -6.77493
## Geodetic CRS: WGS 84
## ID_0 COUNTRY NAME_1 NL_NAME_1 ID_2 NAME_2 VARNAME_2 NL_NAME_2
## 1 IDN Indonesia Jawa Tengah <NA> IDN.10.23_1 Pemalang <NA> <NA>
## TYPE_2 ENGTYPE_2 CC_2 HASC_2 geometry
## 1 Kabupaten Regency 3327 ID.JT.PL MULTIPOLYGON (((109.2517 -7...
print(names(pemalang))
## [1] "ID_0" "COUNTRY" "NAME_1" "NL_NAME_1" "ID_2" "NAME_2"
## [7] "VARNAME_2" "NL_NAME_2" "TYPE_2" "ENGTYPE_2" "CC_2" "HASC_2"
## [13] "geometry"
# Jika tidak ada kolom numeric untuk peta, bikin kolom contoh 'value' (untuk choropleth)
if(!"value" %in% names(pemalang)){
set.seed(2025)
pemalang$value <- sample(50:400, size = nrow(pemalang), replace = TRUE)
message("Kolom 'value' tidak ditemukan. Dibuat kolom contoh 'value' (random) untuk demo.")
}
## Kolom 'value' tidak ditemukan. Dibuat kolom contoh 'value' (random) untuk demo.
# Palet warna
pal <- colorBin("YlOrRd", domain = pemalang$value, bins = 6, na.color = "#CCCCCC")
labels <- paste0(
"<strong>", ifelse("name" %in% names(pemalang), pemalang$name, paste("Unit", seq_len(nrow(pemalang)))),
"</strong><br/>Value: ", formatC(pemalang$value, format="d", big.mark=",")
) %>% lapply(htmltools::HTML)
m <- leaflet(pemalang) %>%
addProviderTiles("CartoDB.Positron") %>%
addPolygons(
fillColor = ~pal(value),
weight = 0.6,
opacity = 1,
color = "white",
dashArray = "3",
fillOpacity = 0.8,
highlightOptions = highlightOptions(weight = 2, color = "#666", dashArray = "", fillOpacity = 0.9, bringToFront = TRUE),
label = labels,
labelOptions = labelOptions(direction = "auto")
) %>%
addLegend(pal = pal, values = ~value, opacity = 0.8, title = "Value", position = "bottomright")
m # interaktif, akan tampil pada knitted HTML
# saveWidget(m, "pemalang_choropleth.html", selfcontained = TRUE)
# Buat data demo untuk polar chart
polar_df <- tibble::tibble(
category = paste0("Kec.", seq_len(8)),
value = sample(50:300, 8)
) %>%
arrange(value) %>%
mutate(category = factor(category, levels = category))
polar_df
## # A tibble: 8 × 2
## category value
## <fct> <int>
## 1 Kec.2 59
## 2 Kec.7 76
## 3 Kec.4 162
## 4 Kec.6 181
## 5 Kec.1 236
## 6 Kec.5 253
## 7 Kec.3 254
## 8 Kec.8 264
# Plot: bar -> polar
p_polar <- ggplot(polar_df, aes(x = category, y = value)) +
geom_col(alpha = 0.9) +
coord_polar(theta = "x") +
labs(title = "Polar Area Chart (Coxcomb)", x = NULL, y = NULL) +
theme_minimal(base_size = 14) +
theme(
axis.text.y = element_blank(),
axis.ticks = element_blank(),
panel.grid = element_blank(),
axis.text.x = element_text(size = 11, face = "bold")
)
p_polar
Hasil visualisasi Polar Area Chart (Coxcomb) menunjukkan adanya variasi nilai antar kecamatan. Kecamatan 3, Kecamatan 5, dan Kecamatan 8 memiliki sektor yang paling panjang, menandakan nilai tertinggi dibandingkan kecamatan lainnya. Kecamatan 1, Kecamatan 6, dan Kecamatan 4 berada pada posisi menengah, sedangkan Kecamatan 2 dan Kecamatan 7 tampak memiliki nilai paling rendah karena luas sektornya relatif kecil. Temuan ini mengindikasikan adanya ketimpangan distribusi antar kecamatan, di mana beberapa kecamatan mendominasi dengan nilai besar, sementara yang lain relatif rendah. Interpretasi lebih lanjut akan sangat bergantung pada konteks data yang digunakan, apakah nilai tersebut merepresentasikan jumlah penduduk, hasil produksi, atau indikator lain yang menjadi fokus analisis.
# Contoh data time-series untuk stream graph
set.seed(2025)
months <- seq.Date(from = as.Date("2024-01-01"), by = "month", length.out = 24)
series_names <- paste0("Sektor_", 1:5)
stream_df <- expand.grid(month = months, series = series_names) %>%
as_tibble() %>%
arrange(series, month) %>%
mutate(value = round(abs(rnorm(n(), mean = 100, sd = 60))) + sample(0:50, n(), replace = TRUE))
# Tampilkan ringkasan
stream_df %>% group_by(series) %>% summarize(total = sum(value)) %>% arrange(desc(total))
## # A tibble: 5 × 2
## series total
## <fct> <dbl>
## 1 Sektor_1 3468
## 2 Sektor_2 2971
## 3 Sektor_3 2920
## 4 Sektor_4 2752
## 5 Sektor_5 2692
# Plot stream
p_stream <- ggplot(stream_df, aes(x = month, y = value, fill = series)) +
geom_stream(type = "proportional") + # type can be "ridge", "proportional", or "mirror"
labs(title = "Stream Graph - Contoh Perkembangan Sektor (bulan)", x = "Bulan", y = "Value") +
theme_minimal(base_size = 12) +
scale_x_date(date_labels = "%Y-%m", date_breaks = "3 months") +
theme(
axis.text.x = element_text(angle = 45, hjust = 1)
)
p_stream
Stream graph ini memperlihatkan bahwa Sektor_1 adalah sektor dominan selama hampir dua tahun pengamatan, diikuti oleh Sektor_2. Sementara itu, Sektor_3 dan Sektor_4 menunjukkan dinamika naik-turun yang cukup signifikan, sedangkan Sektor_5 tetap relatif kecil kontribusinya. Dengan kata lain, struktur kontribusi antar sektor relatif stabil, meskipun sektor menengah (3 & 4) memiliki pola fluktuatif.
# Data contoh: distribusi nilai per kecamatan
set.seed(123)
violin_df <- tibble::tibble(
kecamatan = rep(paste0("Kec.", 1:6), each = 100),
value = c(
rnorm(100, mean = 80, sd = 15),
rnorm(100, mean = 95, sd = 20),
rnorm(100, mean = 70, sd = 10),
rnorm(100, mean = 110, sd = 25),
rnorm(100, mean = 90, sd = 18),
rnorm(100, mean = 100, sd = 22)
)
)
p_violin <- ggplot(violin_df, aes(x = kecamatan, y = value, fill = kecamatan)) +
geom_violin(trim = FALSE, alpha = 0.8) +
geom_boxplot(width = 0.1, outlier.size = 0.5, alpha = 0.6) +
theme_minimal(base_size = 14) +
labs(title = "Violin Plot Distribusi Nilai per Kecamatan", x = "Kecamatan", y = "Value") +
theme(legend.position = "none")
p_violin
Berdasarkan violin plot, terlihat bahwa distribusi nilai antar kecamatan memiliki pola yang berbeda. Kecamatan 4 menunjukkan nilai median paling tinggi dengan sebaran yang luas, sedangkan Kecamatan 3 memiliki median paling rendah dengan variasi nilai yang relatif sempit. Sementara itu, Kecamatan 1, 2, 5, dan 6 berada pada kisaran menengah dengan sebaran data yang cukup bervariasi. Hal ini mengindikasikan adanya perbedaan tingkat nilai dan keragaman data antar kecamatan.
# install.packages("circlize") jika belum ada
library(circlize)
## Warning: package 'circlize' was built under R version 4.5.1
## ========================================
## circlize version 0.4.16
## CRAN page: https://cran.r-project.org/package=circlize
## Github page: https://github.com/jokergoo/circlize
## Documentation: https://jokergoo.github.io/circlize_book/book/
##
## If you use it in published research, please cite:
## Gu, Z. circlize implements and enhances circular visualization
## in R. Bioinformatics 2014.
##
## This message can be suppressed by:
## suppressPackageStartupMessages(library(circlize))
## ========================================
# Data relasi contoh antar kecamatan (matriks adjacency)
set.seed(42)
mat <- matrix(sample(50:200, 36, replace = TRUE), nrow = 6, ncol = 6)
rownames(mat) <- colnames(mat) <- paste0("Kec.", 1:6)
mat
## Kec.1 Kec.2 Kec.3 Kec.4 Kec.5 Kec.6
## Kec.1 98 177 159 138 52 199
## Kec.2 114 96 69 76 107 107
## Kec.3 123 73 163 158 91 185
## Kec.4 195 120 160 54 73 85
## Kec.5 171 149 180 141 92 117
## Kec.6 98 138 90 153 192 195
# Reset circlize plot
circos.clear()
chordDiagram(mat, transparency = 0.25, grid.col = RColorBrewer::brewer.pal(6,"Set2"))
title("Chord Diagram Relasi Antar Kecamatan")
Berdasarkan chord diagram, terlihat bahwa seluruh kecamatan memiliki relasi satu sama lain dengan tingkat keterhubungan yang bervariasi. Kecamatan 2, Kecamatan 4, dan Kecamatan 6 tampak memiliki interaksi yang lebih dominan dibanding kecamatan lainnya, sedangkan kecamatan lain tetap terhubung namun dengan intensitas yang lebih kecil. Hal ini menunjukkan adanya pola hubungan yang kompleks antar kecamatan dalam data yang dianalisis.
library(plotly)
## Warning: package 'plotly' was built under R version 4.5.1
##
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
##
## last_plot
## The following object is masked from 'package:stats':
##
## filter
## The following object is masked from 'package:graphics':
##
## layout
months <- month.abb[1:12]
series <- c("Sektor A","Sektor B","Sektor C")
bar3d_df <- expand.grid(month = months, series = series) %>%
mutate(value = sample(50:200, n(), replace = TRUE))
bar3d_df
## month series value
## 1 Jan Sektor A 158
## 2 Feb Sektor A 141
## 3 Mar Sektor A 53
## 4 Apr Sektor A 148
## 5 May Sektor A 163
## 6 Jun Sektor A 55
## 7 Jul Sektor A 183
## 8 Aug Sektor A 179
## 9 Sep Sektor A 165
## 10 Oct Sektor A 52
## 11 Nov Sektor A 167
## 12 Dec Sektor A 198
## 13 Jan Sektor B 51
## 14 Feb Sektor B 151
## 15 Mar Sektor B 187
## 16 Apr Sektor B 89
## 17 May Sektor B 54
## 18 Jun Sektor B 82
## 19 Jul Sektor B 152
## 20 Aug Sektor B 158
## 21 Sep Sektor B 122
## 22 Oct Sektor B 125
## 23 Nov Sektor B 58
## 24 Dec Sektor B 84
## 25 Jan Sektor C 65
## 26 Feb Sektor C 150
## 27 Mar Sektor C 118
## 28 Apr Sektor C 167
## 29 May Sektor C 179
## 30 Jun Sektor C 131
## 31 Jul Sektor C 162
## 32 Aug Sektor C 195
## 33 Sep Sektor C 118
## 34 Oct Sektor C 159
## 35 Nov Sektor C 153
## 36 Dec Sektor C 89
library(plotly)
library(dplyr)
months <- month.abb[1:12]
series <- c("Sektor A","Sektor B","Sektor C")
bar3d_df <- expand.grid(month = months, series = series) %>%
mutate(value = sample(50:200, n(), replace = TRUE))
# encode month & series sebagai angka unik
bar3d_df <- bar3d_df %>%
mutate(
x = as.numeric(factor(month, levels = month.abb[1:12])),
y = as.numeric(factor(series, levels = unique(series))),
z = value
)
# plot 3D scatter (simulasi bar chart)
p_bar3d <- plot_ly(
bar3d_df,
x = ~x,
y = ~y,
z = ~z,
type = "scatter3d",
mode = "markers",
marker = list(size = 8, color = ~z, colorscale = "Viridis", showscale = TRUE),
text = ~paste("Month:", month, "<br>Series:", series, "<br>Value:", value),
hoverinfo = "text"
) %>%
layout(
scene = list(
xaxis = list(title = "Bulan", tickvals = 1:12, ticktext = month.abb[1:12]),
yaxis = list(title = "Sektor", tickvals = 1:3, ticktext = unique(series)),
zaxis = list(title = "Value")
),
title = "Multiple Series 3D Scatter (Bar-like) Chart"
)
p_bar3d