Dokumen ini memuat perbaikan beberapa visualisasi . Tiap bagian disusun dalam tiga bagian, yaitu alasan perbaikan, perbaikan yang dilakukan, dan interpretasi. Grafik hasil perbaikan ditampilkan di antara bagian kedua dan ketiga.
Catatan data. Seluruh data di dokumen ini adalah
data bangkitan (simulasi) yang dibuat sendiri untuk keperluan latihan,
mengikuti pola gambar pada slide. Data yang mengandung unsur acak
memakai set.seed supaya hasilnya sama setiap kali
dijalankan. Fokus tugas ini ada pada cara memvisualisasikan, jadi angka
pastinya tidak dijadikan patokan dan tidak bersumber dari lembaga mana
pun.
data_bor <- data.frame(
tanggal = c("29 Jan", "30 Jan", "31 Jan", "1 Feb"),
keterisian = c(54, 57, 57, 60)
)
data_bor$tanggal <- factor(data_bor$tanggal, levels = data_bor$tanggal)
ggplot(data_bor, aes(x = tanggal, y = keterisian, group = 1)) +
geom_line(color = "#1f4e79", linewidth = 1.2) +
geom_point(color = "#1f4e79", size = 3.5) +
geom_text(aes(label = paste0(keterisian, "%")), vjust = -1, size = 4.2) +
scale_y_continuous(limits = c(0, 100), labels = function(x) paste0(x, "%")) +
labs(
title = "Keterisian Tempat Tidur RS di DKI Jakarta Naik dari 54% menjadi 60%",
subtitle = "Periode 29 Januari sampai 1 Februari",
x = "Tanggal", y = "Tingkat keterisian tempat tidur",
caption = "Data bangkitan untuk latihan visualisasi"
) +
theme_minimal(base_size = 13) +
theme(plot.title = element_text(face = "bold"),
panel.grid.minor = element_blank())
Keterisian tempat tidur rumah sakit di DKI Jakarta naik dari 54% pada 29 Januari menjadi 60% pada 1 Februari. Kenaikannya bertahap, yaitu 3 poin persentase di hari pertama, tidak berubah di hari berikutnya, lalu naik 3 poin lagi. Totalnya 6 poin persentase dalam empat hari dengan rata-rata sekitar 57%. Pola ini menandakan kebutuhan rawat inap terus bertambah sehingga kapasitas perlu dipantau.
data_bayar <- data.frame(
metode = c("M-Banking", "COD", "Lainnya", "Paylater/Cicilan"),
persen = c(64, 20, 14, 2)
)
data_bayar <- data_bayar %>%
mutate(
metode = factor(metode, levels = metode),
pos = cumsum(persen) - persen / 2,
label = paste0(metode, "\n", persen, "%")
)
warna <- c("M-Banking" = "#0072B2", "COD" = "#E69F00",
"Lainnya" = "#009E73", "Paylater/Cicilan" = "#CC79A7")
ggplot(data_bayar, aes(x = 1, y = persen, fill = metode)) +
geom_col(width = 1, color = "white", linewidth = 1.2,
position = position_stack(reverse = TRUE)) +
geom_text(aes(x = 1.75, y = pos, label = label),
size = 4.3, lineheight = 0.95) +
coord_polar(theta = "y", start = 0) +
scale_fill_manual(values = warna, guide = "none") +
labs(
title = "M-Banking Menjadi Metode Pembayaran Pilihan Utama Pelanggan (64%)",
subtitle = "Persentase pelanggan menurut metode pembayaran",
caption = "Data bangkitan untuk latihan visualisasi"
) +
theme_void(base_size = 13) +
theme(
plot.title = element_text(face = "bold", hjust = 0.5),
plot.subtitle = element_text(hjust = 0.5),
plot.caption = element_text(hjust = 0.5),
plot.background = element_rect(fill = "white", color = NA),
plot.margin = margin(10, 20, 10, 20)
)
Metode pembayaran yang paling banyak dipilih pelanggan adalah M-Banking dengan 64%, jauh di atas COD yang berada di 20%. Kategori Lainnya mencakup 14% pelanggan dan Paylater/Cicilan paling jarang dipakai dengan hanya 2%. M-Banking dipilih hampir tiga kali lipat lebih banyak daripada COD, dan keduanya bersama-sama mencakup 84% pelanggan.
# Data bangkitan mengikuti pola grafik pada slide.
set.seed(2026)
tgl <- seq(as.Date("2020-01-22"), as.Date("2020-08-31"), by = "day")
kunci <- data.frame(
t = as.Date(c("2020-01-22","2020-02-15","2020-03-02","2020-03-18",
"2020-04-03","2020-05-05","2020-05-29","2020-06-22",
"2020-07-08","2020-07-24","2020-08-09","2020-08-31")),
y = c(0, 4000, 2500, 25000, 75000, 85000, 120000, 160000,
210000, 255000, 262000, 260000)
)
dasar <- approx(as.numeric(kunci$t), kunci$y, xout = as.numeric(tgl))$y
pola <- c(0.80, 0.97, 1.03, 1.05, 1.04, 1.02, 0.90)
hari <- as.POSIXlt(tgl)$wday + 1
covid <- data.frame(
tanggal = tgl,
kasus_baru = round(dasar * pola[hari] * exp(rnorm(length(tgl), 0, 0.04)))
)
covid <- covid %>%
mutate(
rata3 = rollmean(kasus_baru, k = 3, fill = NA, align = "right"),
rata7 = rollmean(kasus_baru, k = 7, fill = NA, align = "right")
)
tgl_akhir <- max(covid$tanggal)
n3 <- covid$rata3[covid$tanggal == tgl_akhir]
n7 <- covid$rata7[covid$tanggal == tgl_akhir]
ggplot(covid, aes(x = tanggal)) +
geom_col(aes(y = kasus_baru), fill = "#d9dce0", width = 1) +
geom_line(aes(y = rata3), color = "#E69F00", linewidth = 0.7, na.rm = TRUE) +
geom_line(aes(y = rata7), color = "#0072B2", linewidth = 1.4, na.rm = TRUE) +
annotate("text", x = tgl_akhir, y = max(n3, n7) * 1.25,
label = "Rata-rata 7 hari", color = "#0072B2",
hjust = 1, fontface = "bold", size = 4) +
annotate("text", x = tgl_akhir, y = min(n3, n7) * 0.72,
label = "Rata-rata 3 hari", color = "#E69F00",
hjust = 1, fontface = "bold", size = 4) +
annotate("text", x = as.Date("2020-02-10"), y = max(covid$kasus_baru) * 1.02,
label = "Batang abu-abu: kasus harian",
color = "grey40", size = 3.8, hjust = 0) +
scale_x_date(date_breaks = "1 month", date_labels = "%b %Y") +
scale_y_continuous(labels = label_number(big.mark = ".", decimal.mark = ","),
expand = expansion(mult = c(0, 0.05))) +
labs(
title = "Semakin Panjang Rentang Rata-rata Bergerak, Semakin Jelas Tren Kasus Harian",
subtitle = "Kasus baru harian, rata-rata 3 hari, dan rata-rata 7 hari (data simulasi)",
x = NULL, y = "Kasus baru per hari",
caption = "Data bangkitan untuk latihan visualisasi"
) +
theme_minimal(base_size = 13) +
theme(plot.title = element_text(face = "bold"),
panel.grid.major.x = element_blank(),
panel.grid.minor = element_blank())
Batang abu-abu memperlihatkan kasus harian yang naik turun tajam dari hari ke hari. Rata-rata 3 hari meredam sebagian fluktuasi itu, tetapi garisnya masih bergerigi. Rata-rata 7 hari paling mulus dan menampilkan arah tren yang sebenarnya, yaitu naik tajam sejak Maret, melandai pada April sampai Mei, naik lagi mulai Juni, lalu relatif mendatar di sekitar 260 ribu kasus per hari menjelang akhir periode.
library(ggplot2)
library(dplyr)
library(scales)
# Data ekspor kopi Indonesia 2018 berdasarkan slide
kopi <- data.frame(
negara = c("Amerika Serikat", "Malaysia", "Jepang", "Mesir", "Italia",
"Jerman", "Maroko", "Georgia", "Singapura", "Inggris"),
berat = c(52.1, 37.3, 30.2, 29.1, 27.8, 13.1, 11.2, 10.8, 7.6, 7.4)
)
# Pengurutan faktor agar batang tertinggi berada di posisi paling atas pada coord_flip
kopi <- kopi %>%
arrange(desc(berat)) %>%
mutate(
sorot = ifelse(negara == "Amerika Serikat", "Utama", "Lainnya"),
negara = factor(negara, levels = rev(negara))
)
ggplot(kopi, aes(x = negara, y = berat, fill = sorot)) +
geom_col(width = 0.7) +
geom_text(aes(label = paste0(format(berat, nsmall = 1), " ribu ton")),
hjust = -0.15, size = 3.8) +
scale_fill_manual(values = c("Utama" = "#1F4E79", "Lainnya" = "#B0B7BF"), guide = "none") +
scale_y_continuous(limits = c(0, 62), expand = c(0, 0)) +
coord_flip() +
labs(
title = "Amerika Serikat Menjadi Tujuan Ekspor Kopi Terbesar Indonesia pada 2018",
subtitle = "Sepuluh negara tujuan ekspor kopi berdasarkan berat bersih (ribu ton)",
x = NULL,
y = "Berat Bersih (ribu ton)",
caption = "Sumber: Badan Pusat Statistik (BPS), 2018"
) +
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 13),
panel.grid.major.y = element_blank(),
panel.grid.minor = element_blank(),
plot.margin = margin(10, 20, 10, 10)
)
Amerika Serikat merupakan negara tujuan ekspor kopi terbesar dari Indonesia pada tahun 2018, dengan volume mencapai lebih dari 52 ribu ton. Jumlah ini jauh melampaui negara tujuan lainnya, seperti Malaysia (sekitar 37 ribu ton) dan Jepang (sekitar 30 ribu ton).
Terdapat perbedaan yang cukup signifikan antara 5 negara tujuan teratas (Amerika Serikat, Malaysia, Jepang, Mesir, dan Italia) yang masing-masing mengimpor di atas 25 ribu ton, dibanding 5 negara bawah (Jerman, Maroko, Georgia, Singapura, dan Inggris) yang angka impornya berada di bawah 15 ribu ton. Visualisasi ini menunjukkan konsentrasi pasar ekspor kopi Indonesia yang masih bertumpu pada beberapa negara konsumen utama.
library(ggplot2)
library(dplyr)
library(scales)
# Data ekspor 2019 dengan cakupan benua yang jelas
ekspor_benua <- data.frame(
negara = c("China", "Jepang", "India", "Singapura", "Malaysia",
"Amerika Serikat",
"Belanda", "Jerman", "Spanyol", "Inggris",
"Australia"),
benua = c("Asia", "Asia", "Asia", "Asia", "Asia",
"Amerika Utara",
"Eropa", "Eropa", "Eropa", "Eropa",
"Oceania"),
nilai = c(17, 11, 8, 7, 5.5,
10,
2.0, 1.8, 1.2, 1.0,
2.5)
)
ggplot(ekspor_benua, aes(x = reorder(negara, nilai), y = nilai, fill = benua)) +
geom_col(width = 0.7, show.legend = FALSE) +
geom_text(aes(label = paste0(nilai, "%")), hjust = -0.15, size = 3.5) +
facet_wrap(~ benua, scales = "free_y", ncol = 2) +
scale_fill_manual(values = c("Asia" = "#0072B2", "Amerika Utara" = "#E69F00",
"Eropa" = "#009E73", "Oceania" = "#CC79A7")) +
scale_y_continuous(limits = c(0, 20), expand = c(0, 0)) +
coord_flip() +
labs(
title = "Pasar Ekspor Utama Indonesia Didominasi Asia, disusul Amerika & Eropa",
subtitle = "Persentase nilai ekspor Indonesia tahun 2019 dikelompokkan berdasarkan benua",
x = NULL,
y = "Persentase Nilai Ekspor (%)",
caption = "Sumber: BPS, 2019 (Data olahan latihan)"
) +
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(face = "bold"),
strip.background = element_rect(fill = "grey90", color = NA),
strip.text = element_text(face = "bold"),
panel.grid.major.y = element_blank(),
panel.grid.minor = element_blank()
)
Ekspor Indonesia pada 2019 terkonsentrasi di Asia. China dan Jepang tampak sebagai dua tujuan terbesar, disusul Singapura, India, dan Malaysia. Amerika Serikat menjadi tujuan terbesar di luar Asia, sedangkan kawasan Eropa terdiri dari banyak negara dengan porsi kecil masing-masing. Pola ini menunjukkan ketergantungan pada beberapa pasar utama.
Tiga grafik pada slide masing-masing hanya memuat sebagian informasi. - Grafik pertama hanya sebaran titik tanpa garis yang merangkum arah hubungan. - Grafik kedua punya garis tren tetapi menganggap semua titik satu kelompok, sehingga perbedaan jenis BBM tidak tampak. - Grafik ketiga membedakan jenis BBM tetapi tidak punya garis tren. - Pembaca harus membandingkan ketiganya sendiri untuk mendapat gambaran utuh, dan titik yang saling menumpuk menyulitkan pembacaan kepadatan data.
Dari ketiganya, versi terbaik adalah gabungan grafik kedua dan ketiga. - Titik diwarnai menurut jenis BBM dengan dua warna kontras yang aman bagi buta warna. - Garis tren (loess) ditambahkan dengan warna netral supaya tidak bersaing dengan warna kelompok, lengkap dengan pita interval kepercayaan. - Transparansi titik dipertahankan agar area padat tetap terbaca.
# Data simulasi mengikuti pola scatter pada slide.
set.seed(2026)
n_gas <- 150
n_diesel <- 25
berat_gas <- pmin(pmax(rnorm(n_gas, 2700, 560), 1500), 4050)
berat_diesel <- runif(n_diesel, 2200, 3800)
mobil <- data.frame(
berat = c(berat_gas, berat_diesel),
fuel.type = rep(c("gas", "diesel"), c(n_gas, n_diesel))
)
mobil$jarak <- 22.5 * (1500 / mobil$berat)^0.9 *
exp(rnorm(nrow(mobil), 0, 0.07)) *
ifelse(mobil$fuel.type == "diesel", 1.15, 1)
ggplot(mobil, aes(x = berat, y = jarak)) +
geom_point(aes(color = fuel.type), size = 3.5, alpha = 0.6) +
geom_smooth(method = "loess", se = TRUE,
color = "grey20", fill = "grey70", linewidth = 1.1) +
scale_color_manual(values = c("diesel" = "#D55E00", "gas" = "#0072B2"),
labels = c("diesel" = "Diesel", "gas" = "Bensin/Gas"),
name = "Jenis bahan bakar") +
labs(
title = "Makin Berat Kendaraan, Makin Pendek Jarak Tempuh per Liter BBM",
subtitle = "Kendaraan diesel cenderung menempuh jarak lebih jauh pada berat yang sama",
x = "Berat bersih kendaraan (kg)",
y = "Jarak tempuh per liter BBM (km)",
caption = "Data simulasi mengikuti pola slide"
) +
theme_minimal(base_size = 13) +
theme(plot.title = element_text(face = "bold"),
legend.position = "top")
Terdapat hubungan negatif antara berat kendaraan dan jarak tempuh per liter BBM. Kendaraan yang lebih berat cenderung menempuh jarak lebih pendek, dari sekitar 20 km per liter pada berat 1.500 sampai 2.000 kg menjadi kurang dari 10 km per liter pada berat di atas 3.500 kg. Garis tren melengkung dengan penurunan paling curam di rentang berat yang lebih ringan, lalu melandai pada kendaraan yang lebih berat. Titik diesel umumnya berada di atas titik gas pada berat yang sama, yang menunjukkan kendaraan diesel cenderung lebih irit. Jumlah titik diesel jauh lebih sedikit, jadi perbandingan ini harus dibaca hati-hati. Grafik ini hanya menunjukkan asosiasi dan bukan sebab akibat, karena faktor lain seperti ukuran mesin juga bisa memengaruhi konsumsi BBM.
# Data simulasi mengikuti pola slide (kasus harian, April 2020 - Maret 2021).
set.seed(2026)
tgl <- seq(as.Date("2020-04-01"), as.Date("2021-03-31"), by = "day")
kunci <- data.frame(
t = as.Date(c("2020-04-01","2020-06-15","2020-07-15","2020-08-31",
"2020-10-10","2020-11-25","2020-12-15","2021-01-01",
"2021-01-20","2021-02-05","2021-02-15","2021-03-01",
"2021-03-31")),
y = c(100, 130, 250, 550, 1180, 800, 1250, 1700,
2700, 3200, 2400, 1500, 1350)
)
dasar <- approx(as.numeric(kunci$t), kunci$y, xout = as.numeric(tgl))$y
pola <- c(0.75, 1.0, 1.08, 1.1, 1.05, 1.0, 0.85)
hari <- as.POSIXlt(tgl)$wday + 1
kasus <- data.frame(
tanggal = tgl,
kasus_baru = round(dasar * pola[hari] * exp(rnorm(length(tgl), 0, 0.12)))
)
kasus <- kasus %>%
mutate(rata7 = rollmean(kasus_baru, k = 7, fill = NA, align = "right"))
puncak <- kasus %>% filter(rata7 == max(rata7, na.rm = TRUE)) %>% slice(1)
ggplot(kasus, aes(x = tanggal)) +
geom_col(aes(y = kasus_baru), fill = "#d9dce0", width = 1) +
geom_area(aes(y = rata7), fill = "#0072B2", alpha = 0.35, na.rm = TRUE) +
geom_line(aes(y = rata7), color = "#0072B2", linewidth = 1.2, na.rm = TRUE) +
geom_point(data = puncak, aes(y = rata7), color = "#D55E00", size = 4) +
geom_text(data = puncak,
aes(y = rata7,
label = paste0("Puncak: ", format(tanggal, "%d %b %Y"),
"\n", format(round(rata7), big.mark = "."),
" kasus/hari")),
vjust = -0.5, color = "#D55E00", fontface = "bold", size = 3.8) +
scale_x_date(date_breaks = "2 months", date_labels = "%b %Y") +
scale_y_continuous(labels = label_number(big.mark = "."),
expand = expansion(mult = c(0, 0.2))) +
labs(
title = "Kasus Harian Naik dalam Dua Gelombang dan Mencapai Puncak pada Awal 2021",
subtitle = "Garis dan area biru: rata-rata bergerak 7 hari. Batang abu-abu: kasus harian",
x = NULL, y = "Kasus baru per hari",
caption = "Data simulasi mengikuti pola slide"
) +
theme_minimal(base_size = 13) +
theme(plot.title = element_text(face = "bold"),
panel.grid.major.x = element_blank(),
panel.grid.minor = element_blank())
Kasus baru harian bertahan rendah di awal periode, lalu naik bertahap mulai pertengahan 2020 hingga membentuk gelombang pertama di sekitar Oktober 2020. Setelah itu angkanya sempat turun, naik lagi lebih tinggi, dan mencapai puncak pada awal 2021 di kisaran 3.200 kasus per hari menurut rata-rata 7 hari. Sesudah puncak, kasus turun cukup cepat sampai akhir periode. Jadi pola yang tampak adalah dua gelombang dengan gelombang kedua jauh lebih besar. Rata-rata bergerak meredam fluktuasi harian, tetapi membuat puncak tampak lebih rendah dan sedikit terlambat dibanding data mentah, dan cara ini tidak menghilangkan keterlambatan pelaporan. Angka yang dipakai adalah simulasi yang mengikuti pola slide.
library(ggplot2)
library(dplyr)
library(tidygraph)
library(ggraph)
set.seed(2026)
negara <- c("Indonesia", "Singapura", "Malaysia", "Thailand",
"Vietnam", "Filipina", "Kamboja")
# 1. Matriks Data Simulasi Perdagangan (miliar USD)
dagang <- expand.grid(from = negara, to = negara, stringsAsFactors = FALSE) %>%
filter(from != to) %>%
mutate(nilai = round(rexp(n(), rate = 1/10) + 1, 1))
# 2. Hitung Rincian Ekspor, Impor, dan Total Perdagangan per Negara
ekspor_df <- dagang %>% group_by(from) %>% summarize(total_ekspor = sum(nilai))
impor_df <- dagang %>% group_by(to) %>% summarize(total_impor = sum(nilai))
ringkasan_perdagangan <- full_join(ekspor_df, impor_df, by = c("from" = "to")) %>%
rename(name = from) %>%
mutate(
total_dagang = total_ekspor + total_impor,
label_node = paste0(name, "\nTotal: ", sprintf("%.1f", total_dagang), " M USD",
"\n(X: ", sprintf("%.1f", total_ekspor), " | M: ", sprintf("%.1f", total_impor), ")")
)
# 3. Filter Aliran Perdagangan Utama untuk Garis Jaringan
batas <- quantile(dagang$nilai, 0.65)
dagang_filter <- dagang %>%
filter(nilai >= batas | from == "Indonesia") %>%
mutate(fokus = ifelse(from == "Indonesia", "Ekspor Indonesia", "Aliran lain"))
tujuan_utama <- dagang %>% filter(from == "Indonesia") %>% slice_max(nilai, n = 1)
# 4. Buat Graf
g <- tbl_graph(nodes = ringkasan_perdagangan, edges = dagang_filter, directed = TRUE)
# Kalkulasi Tata Letak Melingkar
layout_g <- create_layout(g, layout = "circle")
ggraph(layout_g) +
# Garis panah aliran ekspor antarnegara (sudah diperbaiki di baris alpha)
geom_edge_arc(aes(edge_width = nilai, edge_colour = fokus),
strength = 0.15, alpha = 0.5,
arrow = arrow(length = unit(2.5, "mm"), type = "closed"),
start_cap = circle(7, "mm"), end_cap = circle(7, "mm")) +
# Node/Titik Negara
geom_node_point(aes(size = total_dagang, fill = ifelse(name == "Indonesia", "Indonesia", "Lainnya")),
shape = 21, color = "white", stroke = 1.2) +
# Label Teks Lengkap di Luar Lingkaran
geom_node_text(aes(label = label_node),
nudge_x = layout_g$x * 0.25,
nudge_y = layout_g$y * 0.25,
size = 3.3, fontface = "bold", lineheight = 0.85) +
scale_edge_width(range = c(0.4, 2.5), name = "Nilai Transaksi Ekspor (miliar USD)") +
scale_edge_colour_manual(values = c("Ekspor Indonesia" = "#D55E00", "Aliran lain" = "#9AA5B1"), name = NULL) +
scale_fill_manual(values = c("Indonesia" = "#D55E00", "Lainnya" = "#0072B2"), guide = "none") +
scale_size_continuous(range = c(6, 13), guide = "none") +
labs(
title = paste0("Simulasi Perdagangan ASEAN: Ekspor Indonesia Terbesar Mengarah ke ", tujuan_utama$to),
subtitle = "Catatan: Total Perdagangan = Total Ekspor (X) + Total Impor (M) intra-ASEAN | Tebal garis = Nilai Ekspor",
caption = "Data simulasi latihan | X = Ekspor, M = Impor (Satuan: Miliar USD)"
) +
coord_fixed(clip = "off") +
theme_void(base_size = 12) +
theme(
plot.title = element_text(face = "bold", hjust = 0.5, size = 13),
plot.subtitle = element_text(hjust = 0.5, margin = margin(b = 20), size = 10, color = "grey20"),
plot.caption = element_text(hjust = 0.5, color = "grey40", margin = margin(t = 15)),
legend.position = "bottom",
legend.box = "horizontal",
plot.margin = margin(30, 80, 30, 80)
)
Pusat Jaringan Perdagangan Regional: Singapura mencatatkan nilai Total Perdagangan terbesar dalam simulasi ini, yaitu sebesar 265,0 Miliar USD (dengan perimbangan Ekspor \(X = 132,4\) M USD dan Impor \(M = 132,6\) M USD). Hal ini ditunjukkan oleh ukuran lingkaran biru yang paling besar, mengonfirmasi posisinya sebagai hub utama transaksi barang dan jasa di kawasan ASEAN. Kinerja dan Fokus Ekspor Indonesia: Indonesia mencatatkan total transaksi sebesar 101,4 Miliar USD (\(X = 48,5\) M USD | \(M = 52,9\) M USD). Garis oranye tebal memperlihatkan bahwa tujuan aliran ekspor terbesar Indonesia mengarah ke Thailand