1 Data Visualization

Sebelum Anda melanjutkan dan menjalankan kode-kode dalam coursebook ini, ada baiknya Anda melakukan persiapan dan pengaturan di awal. Di bawah tab Libraries Anda akan melihat beberapa kode untuk menginisialisasi ruang kerja kita, dan library yang akan kita gunakan untuk menjalankan visualisasi data. Anda juga dapat memastikan apakah library yang tercantum dalam list tersebut sudah pernah diinstall sebelumnya. Di bawah tab Training Objectives kami akan menguraikan silabus, mengidentifikasi tujuan utama dan menetapkan goals untuk setiap modul.

1.1 Introduction

1.1.1 Algoritma’s Coursebook

Materi ini diproduksi oleh tim dari Algoritma untuk Bank Indonesia - Automatic Reporting. Materi berikut hanya ditujukan untuk kalangan terbatas, meliputi individu/personal yang menerima materi ini secara langsung dari lembaga pelatihan. Materi ini dilarang untuk direproduksi, didistribusikan, diterjemahkan, atau diadaptasikan dalam bentuk apa pun di luar izin dari individu dan organisasi yang berkepentingan.

Algoritma adalah pusat pendidikan Data Science di Jakarta. Kami mengadakan workshop dan program pelatihan untuk membantu para profesional dan pelajar untuk mendapatkan keahlian dalam berbagai bidang dalam ruang lingkup Data Science: data visualization, machine learning, data modeling, statistical inference, dan lain-lainnya.

Sebelum masuk ke dalam materi dan menjalankan kode-kode di dalam materi ini, silakan anda melihat bagian Library and Setup untuk melihat dan memastikan semua persyaratan dasar untuk mengikuti materi ini sudah terpenuhi termasuk package-package yang diperlukan. Pada bagian Tujuan Pembelajaran anda dapat melihat secara umum apa saja yang akan dipelajari dalam modul materi ini. Kami harap materi ini akan bermanfaat bagi karier ataupun menambah keahlian peserta.

Libraries

Anda perlu menggunakan install.packages() untuk menginstal library apa pun yang tercantum di bawah ini yang belum diunduh ke komputer Anda–periksa daftar library Anda di panel Packages (secara default, di sisi kanan bawah). Untuk memanggil library yang telah diinstall, Anda dapat menggunakan fungsi library():

# import libraries
library(readxl)
library(tidyverse)
library(lubridate)

library(ggplot2)
library(ggthemes)
library(ggpubr)
library(ggalt)
library(cowplot)
library(scales)
library(ggtext)

1.1.2 Training Objectives

Visualisasi data adalah salah satu bagian penting dalam rutinitas pengolahan data. Ini memungkinkan kita untuk mengeksplorasi lebih banyak insight tentang sekumpulan data, serta menyajikan insight yang kita temukan dari kumpulan.

Sepanjang kursus ini, kita akan mencoba beberapa skenario visualisasi dan melakukan beberapa diskusi bersama mengenai opsi visualisasi dan setiap interpretasinya.

Tujuan utama dari kursus ini adalah untuk memberikan pengantar dan sesi langsung untuk membantu peserta mendapatkan kemahiran penuh dalam sistem dan tools visualisasi data. Anda akan belajar membuat narasi yang menarik dengan menggabungkan elemen grafik dengan grammar yang kaya untuk visualisasi.

Berikut silabus materi ini:

  • The Grammar of Graphics
    • Introduction to ggplot2
    • Basic visual enchancement
    • Branding a visualization
    • Many Ways to Visualize a Context
      • Categorical ranking with barplot
      • Time-based evolution with lineplot, etc
  • Advanced enhancement for ggplot

Setelah selesai mengikuti pelatihan ini, peserta dapat meningkatkan kemampuan seperti:

  1. Mempelajari cara mengubah hasil pemodelan abstrak menjadi wawasan yang jelas, dapat ditindaklanjuti, dan dampak yang terukur.
  2. Memahami cara menyajikan dan menerjemahkan data ke wawasan bisnis.

1.2 The Grammar of Graphics with ggplot2

Apa itu ggplot2? ggplot2 adalah sebuah libary yang akan menyediakan sebuah kanvas kosong yang dapat digunakan untuk membuat visualisasi. Sistem pembuatannya akan berdasarkan grammar formula of visualization dan layer by layer. Kedua sistem pembuatannya sangat bisa untuk dikutomisasi sehingga plot yang disajikan nantinya sangat cocok jika ingin ditampilkan kepada audiens.

Grammar formula of ggplot2 ggplot(data = ..., mapping = aes(x=..., y=...)) + geom_... + ...

# import library (hanya perlu dijalankan sekali setelah membuka file Rmd)
library(ggplot2)

ggplot(data = , mapping = aes(x=, y=))

  • Step 1: Mempersiapkan data

Untuk lebih kenal dengan library ggplot2, mari kita lihat contoh sederhana. Kita memili 2 data kategorikal yang masing-masing memiliki 500 numerik value.

# generate data secara random
df <- data.frame(
  name=c( rep("A",500), rep("B",500)),
  value=c( rnorm(500, 10, 5), rnorm(500, 13, 1))
)

df
  • Step 2: Masukan parameter yang diperlukan untuk fungsi ggplot()

Sekarang kita akan membuat objek ggplot menggunakan fungsi ggplot(). Pada tahap ini, unsur visulasisasi yang pertama adalah sumbu pada axis x dan y yang memetakan 2 nilai yaitu name dan value. Perhatikan bahwa kita baru saja membuat plot kosong tanpa elemen geometri (garis, titik, dll) di atasnya. Hal ini seperti Anda sedang menyiapkan kanvas kosong untuk memulai menggambar/melukis di atasnya.

Perhatikan bagaimana fungsi ggplot() membutuhkan dua parameter wajib ketika digunakan:

  • data : mendeskripsikan data yang akan dipakai untuk membuat plot
  • mapping : pada parameter ini akan kita isi dengan aesthetic/aes(), yang memungkinkan kita untuk menentukan pemetaan variabel x dan y sehingga mereka digunakan sesuai dengan ggplot
# membuat objek ggplot
ggplot(data = df, mapping = aes(x = name, y = value))

  • Step 3: Menambahkan layer

Layer 1: Membuat visual boxplot

Setelah kita membuat objek ggplot, sekarang kita dapat menambahkan layer ke atasnya menggunakan fungsi geom_*. geom adalah cara ggplot menangani geometri, yaitu bagaimana data direpresentasikan pada plot. Untuk mengilustrasikan ide ini, mari tambahkan geom_boxplot lalu cetak objek yang dihasilkan:

Untuk menambahkan layer pada main layer, kita bisa menggunakan simbol +

# visualisasi boxplot
ggplot(data = df, mapping = aes(x = name, y = value)) +
  geom_boxplot()

Layer 2: Membuat visual point

Kita juga dapat menambahkan layer lainnya dengan fungsi geom_* sehingga akan menghasilkan layer baru di atas plot yang telah dibuat sebelumnya.

# visualisasi
ggplot(data = df, mapping = aes(x = name, y = value)) +
  geom_boxplot()+
  geom_point()

  • Step Opsional: Mari kita tukar posisi geom_boxplot() dengan geom_point()
# visualisasi
ggplot(data = df, mapping = aes(x = name, y = value)) +
  geom_point() +
  geom_boxplot()

  • Step 4: Menambahkan warna pada plot

Untuk memberikan warna pada plot kita, kita bisa memanfaatkan parameter color atau fill pada fungsi aes()

Menggunakan parameter fill

# Please Type Your Code Down Below
ggplot(data = df, mapping = aes(x = name, y = value, fill = name)) +
  geom_boxplot()+
  geom_point()

Menggunakan parameter color

# Please Type Your Code Down Below
ggplot(data = df, mapping = aes(x = name, y = value, color = name)) +
  geom_boxplot()+
  geom_point()

Pengaruh penempatan parameter pada fungsi aes()

Ditempatkan pada fungsi salah satu geom_

# Please Type Your Code Down Below
ggplot(data = df, mapping = aes(x = name, y = value)) +
  geom_boxplot(mapping = aes(color = name))+
  geom_point()

Rekap dari apa yang telah kita lakukan sejauh ini:

  • Membuat objek grafis ggplot menggunakan fungsi ggplot()
  • Menentukan 2 argumen pada parameter data dan mapping ke dalam fungsi ggplot; Perlu untuk dicatat bahwa parameter apa pun yang kita berikan ke ggplot() akan digunakan sebagai opsi global untuk plot, dan berlaku untuk semua lapisan yang kita tambahkan ke objek grafik tersebut.
  • Untuk argumen kedua kita telah menggunakan fungsi aes(), yang memungkinkan untuk memetakan variabel dari dataframe kita ke properti estetika plot (dalam kasus ini, kita memetakannya ke sumbu x dan y)
  • Kita memberi tahu kepada ggplot bagaimana kita ingin objek grafik direpresentasikan dengan menambahkan (melalui operator “+”) lapisan geom. Contohnya dengan menambahkan geom_boxplot(), ini setara dengan menambahkan lapisan boxplot untuk mewakili variabel x dan y.

Setelah mempelajari sistem dasar bagaimana ggplot bekerja dan menggunakan fungsi geom_* untuk menambahkan unsur geometri, kita akan belajar menggunakan fungsi lain yang dapat mengontrol unsul lain dari konstruksi plot yang telah dibuat. Sebagai contoh, kita dapat mengontrol unsur konstruksi pada ggplot seperti skala, legenda, geom, dan elemen tematik atau ini bisa berupa konstruksi tambahan yang bekerja dengan ggplot melalui third party packages.

1.3 Ragam Konteks Visualisasi

Setelah kita berkenalan dengan konsep dasar dari ggplot, mari kita coba membahas ragam visualisasi yang bisa kita gunakan berdasarkan data yang kita miliki. Tujuan dari pembahasan ini adalah agar kita bisa memilih cara yang paling baik untuk mengkomunikasikan data kita dan audiens akan mendapatkan insight yang ingin akan disampaikan.

Pada bagian ini, kita akan membahas beberapa konteks visualisasi dasar:

  • Categorical ranking
  • Time-based evolution

1.3.1 Categorical Ranking

Categorical ranking adalah salah satu cara paling dasar untuk mengomunikasikan bagaimana variabel kategoris dapat menunjukkan perilaku yang berbeda antara levelnya dalam hal output numerik.

Setelah ini, kita akan membahas cara dasar untuk melakukan pemeringkatan kategoris dan bagaimana memvisualisasikan dataset kita agar pengambilan insight akan lebih mudah dilakukan.

1.3.1.1 General ranking - Bar Plot

Dalam memvisualisasikan peringkat kategoris, kita dapat menggunakan plot batang (barplot) untuk menunjukkan perbedaan besarnya setiap level dalam variabel kategori.

Contoh data yang akan kita gunakan adalah data untuk visual G1. 15 EKSPOR yang membahas peringkat negara dalam hal jumlah ekspor luar negri di sektor non-migas.

  • Step 1: Persiapan data
# data preparation
ekspor_negara <- read_excel(path = "Data/BAB 1.xlsx",
                            sheet = "G1. 15 EKSPOR", 
                            range = cell_rows(9:14))

# print data
ekspor_negara
  • Step 2: Mempersiapkan template ggplot()
# ggplot canvas
ggplot(data = ekspor_negara, mapping = aes(x = negara, y = pangsa))

  • Step 3: Coba visualisasikan dengan geom_col
# ggplot + geom_col()
ggplot(data = ekspor_negara, mapping = aes(x = negara, y = pangsa)) +
  geom_col()

Notes: Hasil visualisasi barplot memang tidak akan terurut dari yang paling besar ke paling kecil, begitu juga sebaliknya, walaupun kita sudah mengurutkan data kita dengan menggunakan fungsi desc().

  • Step 4: Menambahkan parameter reorder() pada sumbu nilai yang mau diurutkan

Fungsi reorder() adalah sebuh parameter yang dapat dimanfaatkan untuk mengurutkan freq

ggplot(data = ekspor_negara, 
       mapping = aes(x = reorder(negara, -pangsa), y = pangsa)) +
  geom_col()

Step 5: Coba kita switch antara kolom x & y pada parameter aes()

ggplot(data = ekspor_negara, 
       mapping = aes(y = reorder(negara, pangsa), x = pangsa)) +
  geom_col()

Step 6: Menambahkan geom_text()

Fungsi geom_text() adalah sebuah fungsi untuk memberikan keteragan angka didalam bar plot + color = Untuk memberikan warna ke text + size = untuk mengatur ukuran text + nudge_x = untuk mengatur orientasi sumbu x

ggplot(data = ekspor_negara, 
       mapping = aes(y = reorder(negara, pangsa), x = pangsa)) +
  geom_col(mapping = aes(fill = negara)) +
  geom_text(mapping = aes(label = percent(pangsa)), 
            size = 2,
            nudge_x =  0.02)

Step 6: Menambahkan keterangan title, subtitle, legends, dan label sumbu x dan y dengan menggunakan fungsi labs()

ggplot(data = ekspor_negara, 
       mapping = aes(y = reorder(negara, pangsa), x = pangsa)) +
  geom_col(mapping = aes(fill = negara)) +
  geom_text(mapping = aes(label = percent(pangsa)), 
            size = 2,
            nudge_x =  0.02) +
  labs(title = "Indeks Penjualan Riil Provinsi Sulawesi Selatan",
       caption = "Source: Bank Indonesia",
       x = NULL,
       y = NULL)

Step 7: Mengatur theme

Pada visualisasi di atas kita masih belum menerapkan tema apapun ke plot. Kita dapat menambahkan tema dengan cara menggunakan beberapa fungsi seperti theme_bw(), theme_minimal(), dan fungsi theme_() lainnya.

ggplot(data = ekspor_negara, 
       mapping = aes(y = reorder(negara, pangsa), x = pangsa)) +
  geom_col(mapping = aes(fill = negara)) +
  geom_text(mapping = aes(label = percent(pangsa)), 
            size = 2,
            nudge_x =  0.02) +
  labs(title = "Indeks Penjualan Riil Provinsi Sulawesi Selatan",
       caption = "Source: Bank Indonesia",
       x = NULL,
       y = NULL) +
  theme_minimal()

Selain dari beberapa tema yang sudah disediakan oleh R, kami juga sudah mempersiapkan sebuah tema untuk BI yang tersimpan pada file theme-BI.R pada folder R. Untuk mengaktifasi tema tersebut kita perlu menggunakan fungsi di bawah ini.

# source our custom themes
source("R/theme-BI.R")

Setelah diaktifasi kita bisa menerapkannya dengan menambahkan fungsi theme_BI().

ggplot(data = ekspor_negara, 
       mapping = aes(y = reorder(negara, pangsa), x = pangsa)) +
  geom_col(mapping = aes(fill = negara)) +
  geom_text(mapping = aes(label = percent(pangsa)), 
            size = 2,
            nudge_x =  0.02) +
  guides(fill = "none")+
  labs(title = "Indeks Penjualan Riil Provinsi Sulawesi Selatan",
       caption = "Source: Bank Indonesia",
       fill = NULL,
       x = NULL,
       y = NULL) +
  theme_BI()

1.3.1.2 General ranking - Pie Plot

Sebagai pertimbangan lainnnya, barplot terkadang dianggap sebagai plot yang “membosankan”. Untuk mengatasinya, Anda juga bisa menggunakan cara alternatif untuk memvisualisasikan peringkat kita dapat membuat pie plot.

Berikut adalah contoh pie plot yang sebelumnya dalam bentuk bar plot.

knitr::include_graphics("assets/pie_plot.PNG")

  • Step 1: Persiapan data

Untuk membuat pie plot, kita akan melakukan persiapan data terlebih dahulu. Tujuan dari persiapan data ini adalah untuk mengurutkan legend negara berdasarkan nilai yang paling tinggi.

# Persiapan data
data_viz <- ekspor_negara %>% 
  mutate(negara=as.factor(negara)) %>% 
  arrange(-pangsa) %>% 
  mutate(legend_labs = paste0(negara, " (", percent(pangsa), ")"))

legend_ord <- levels(with(data_viz, reorder(negara, -pangsa)))
  • Step 2: Membuat Pie Plot

Dalam pembuatan pie plot, kita akan menggunakan 2 fungsi yaitu:

  • Fungsi geom_bar()
    • pada fungsi ini akan kita isi dengan parameter stat = "identity", parameter ini diperuntuhkan untuk menggabungkan beberapa bar plot menjadi satu kesatuan.
  • Fungsi coord_polar(), fungsi inilah yang akan mengubah bar plot menjadi pie plot dengan cara mengisi beberapa parameter berikut ini:
    • theta =, parameter ini untuk mengatur bentuk dari pie plot yang akan ditampilkan (x / y)
    • direction =, parameter ini untuk mengatur arah pembuatan pie plot (clockwise = 1 / anticlocwise = -1)
# Membuat plot
ggplot(data_viz, aes(x="", y=pangsa, fill=negara)) +
  geom_bar(stat="identity") +
  coord_polar("y", direction = -1)

  • Step 3: Mengatur Urutan Legend + Memberikan Warna

Kita dapat mengatur urutan legend, beserta memberikan warna dengan menggunakan fungsi scale_fill_brewer().

ggplot(data_viz, aes(x="", y=pangsa, fill=negara)) +
  geom_bar(stat="identity") +
  coord_polar("y", direction = -1) +
  scale_fill_brewer(palette = "Blues", breaks=legend_ord) 

  • Step 4: Menambahkan Informasi Text

Untuk memperjelas informasi yang dikandung pada pie plot kita, kita akan menggunakan fungsi geom_text(). Akan tetapi terdapat sedikit perbedaan dalam penggunaanya. Berikut contoh syntax yang akan kita gunakan.

geom_text(data = head(data_viz,3), 
          mapping =aes(y = pangsa,
                       label = percent(round(pangsa, digits = 2), accuracy = 0.1)),
          color = "black",
          size=4,
          position = position_stack(vjust = 0.5))
ggplot(data_viz, aes(x="", y=pangsa, fill=negara)) +
  geom_bar(stat="identity") +
  coord_polar("y", direction = -1) +
  scale_fill_brewer(palette = "Blues", breaks=legend_ord) +geom_text(data = head(data_viz,3), 
                    mapping =aes(y = pangsa,
                                  label = percent(round(pangsa, digits = 2), accuracy = 0.1)),
                    color = "black",
                    size=4,
                    position = position_stack(vjust = 0.5))

  • Step 5: Merapikan Visual
# alternative visualization
ggplot(data_viz, aes(x="", y=pangsa, fill=negara)) +
  geom_bar(stat="identity") +
  coord_polar("y", direction = -1)+
  geom_text(data = head(data_viz,3), 
            mapping =aes(y = pangsa,
                         label = scales::percent(round(pangsa, digits = 2), accuracy = 0.1)),
            color = "black",
            size=4,
            position = position_stack(vjust = 0.5))+
  scale_fill_brewer(palette = "BuGn", direction=-1, breaks=legend_ord)+
  theme_void() +
  labs(title = "Negara Tujuan Ekspor",
       subtitle = "(dalam juta USD)",
       x=NULL,
       y=NULL) +
  theme_minimal()+
  theme(legend.title = element_blank(),
        legend.text = element_text(size=7),
        plot.title = element_text(size=10, hjust = .5),
        plot.subtitle = element_text(size=7, hjust = .5),
        axis.text.x = element_blank(),
        panel.grid = element_blank()
        )

Additional Notes: Pie plot tidak disarankan jika kategori data yang dibandingkan sangat besar karena akan sulit untuk mengambil insight untuk nilai terkecil karena areanya akan sangat susah dibedakan.

1.3.2 Multivariate Plot

Seperti pada contoh sebelumnya, memvisualisasikan peringkat kategoris dapat membantu kita memperoleh beberapa insight dengan cepat. Namun, seringkali kita perlu membuat rincian yang lebih detail dari peringkat kategoris untuk mendapatkan lebih banyak insight. Multivariate plot adalah sebuah plot yang digunakan untuk menampilkan nilai dari beragam variabel secara bersamaan. Sebagai contoh, mari coba kita visualisasikan kembali peringkat tetapi dengan memecah pangsa ekonomi PDRB Sulawesi Selatan terhadap wilayah Sulampua (Sulawesi, Maluku, Papua) untuk membuat visualisasi seperti di bawah ini:

knitr::include_graphics("assets/stacked_bar_plot.PNG")

  • Step 1: Persiapan data

Pertama, kita akan membaca data. Ingat, kita telah membuat sebuah fungsi praktis untuk membaca data pada pertemuan sebelumnya. Silahkan jalankan kode berikut untuk memastikan bahwa fungsi tersebut dapat kita panggil kembali nantinya untuk membaca dataset.

# fungsi membaca data
load_data <- function(path, sheet_name, row_range, start_year=2019) {
  varnames <- seq(start_year, 3000, by = 1)
  readxl::read_excel(
        path,
        sheet = sheet_name,
        col_names=F,
        range=cell_rows(row_range),
      ) %>%
  rename_with(.cols = !1,  
              .fn = ~ paste0(rep(varnames, each=4), "_", c("I", "II", "III", "IV"))) %>% 
  rename_with(.cols = 1,
         .fn = ~ paste0("kolom1"))%>%
  pivot_longer(cols = !kolom1, names_to = "quarter", values_to = "values") %>% 
  mutate(year_q = quarter) %>% 
  separate(col = quarter,
           into = c("year", "q"),
           sep = "_")
}
# data preparation
data_g2 <- load_data("Data/BAB 1.xlsx", sheet_name = 2, row_range = 3:8, start_year = 2020)
head(data_g2)

Dari yang kita miliki, jika kita langsung membuat visualisasi, hasilnya tidak akan sama persis dengan gambar yang dilampirkan karena masih ada informasi yang tidak perlu kita tampilkan pada visualisasi. Informasi yang tidak kita butuhkan adalah informasi pada tahun 2020.

# data cleansing
data_g2 <- data_g2 %>% 
  filter(year != 2020)
  
data_g2$kolom1 <- factor(data_g2$kolom1, levels=c("Lainnya", "Papua", "Sulawesi Tenggara", "Sulawesi Tengah", "Sulawesi Utara", "Sulawesi Selatan"))

data_lainnya <- data_g2 %>% filter(kolom1%in%"Lainnya")

# print some examples
head(data_g2)
  • Step 2: Pembuatan Visual

Ketika kita memiliki beberapa data factor/character pada satu kolom dan kita ingin melakukan visulisasi, fungsi geom_col() akan secara otomatis untuk menumpuk informasi data factor tersebut.

ggplot(data = data_g2,
       mapping = aes(y = year_q, x = values)) +
  geom_col(aes(fill = kolom1), width = 0.5)

  • Step 3: Menambahkan informasi tulisan
ggplot(data = data_g2,
       mapping = aes(y = year_q, x = values)) +
  geom_col(aes(fill = kolom1), width = 0.5) +
  geom_text(aes(label = values),
            fontface = "bold",
            position = position_stack(vjust = 0.5),
            size = 2.5,
            color = "white") 

  • Step 4: Mengatur Warna Secara Manual

Selain menggunakan pallete warna yang sudah disediakan, kita juga diberikan kebebasan untuk memberikan warna pada visualisasi kita. Selain memberikan warna kita juga dapat mengatur posisi urutan legend kita secara manual.

Fungsi yang akan kita gunakan adalah scale_fill_manual(), pada fungsi tersebut terdapat 2 parameter yang dapat kita isi yaitu:

  • values =, diperuntuhkan untuk mengisi warna secara manual
  • breaks =, diperuntuhkan untuk mengatur urutan dari legend
scale_fill_manual(values = c("#5b9bd5", "#ed7d31", "#a5a5a5", "#ffc000", "#4472c4", "#70ad47"),
                  breaks = c("Sulawesi Selatan", "Sulawesi Utara", "Sulawesi Tengah", "Sulawesi Tenggara", "Papua", "Lainnya"))
ggplot(data = data_g2,
       mapping = aes(y = year_q, x = values)) +
  geom_col(aes(fill = kolom1), width = 0.5) +
  geom_text(aes(label = values),
            fontface = "bold",
            position = position_stack(vjust = 0.5),
            size = 2.5,
            color = "white") +
  scale_fill_manual(values = c("#5b9bd5", "#ed7d31", "#a5a5a5", "#ffc000", "#4472c4", "#70ad47"),
                    breaks = c("Sulawesi Selatan", "Sulawesi Utara", "Sulawesi Tengah", "Sulawesi Tenggara", "Papua", "Lainnya"))

  • Step 5: Merapikan Label Informasi Sumbu X & Sumbu Y

Sumbu X yang terdapat pada visual kita menunjukan informasi dalam bentuk persentasi, untuk mengubah label tersebut kita akan menggunakan fungsi scale_x_continous()

ggplot(data = data_g2,
       mapping = aes(y = year_q, x = values)) +
  geom_col(aes(fill = kolom1), width = 0.5) +
  geom_text(aes(label = values),
            fontface = "bold",
            position = position_stack(vjust = 0.5),
            size = 2.5,
            color = "white") +
  scale_fill_manual(values = c("#5b9bd5", "#ed7d31", "#a5a5a5", "#ffc000", "#4472c4", "#70ad47"),
                    breaks = c("Sulawesi Selatan", "Sulawesi Utara", "Sulawesi Tengah", "Sulawesi Tenggara", "Papua", "Lainnya")) +
  scale_x_continuous(labels = scales::percent_format(scale = 1))

Menambahkan informasi tahun dan quartal pada sumbu Y. Menambahkan informasi dapat dilakukan dengan menggunakan fungsi annotate(). Berikut contoh syntaxnya:

  annotate(geom = "text",
           y = seq_len(nrow(data_lainnya)),
           x = -3.5,
           label = data_lainnya$q,
           size = 3) +
  annotate(geom = "text",
           y = c(2.5, 5.5),
           x = -9.5,
           label = unique(data_lainnya$year),
           size = 3,
           angle = '90')
ggplot(data = data_g2,
       mapping = aes(y = year_q, x = values)) +
  geom_col(aes(fill = kolom1), width = 0.5) +
  geom_text(aes(label = values),
            fontface = "bold",
            position = position_stack(vjust = 0.5),
            size = 2.5,
            color = "white") +
  scale_fill_manual(values = c("#5b9bd5", "#ed7d31", "#a5a5a5", "#ffc000", "#4472c4", "#70ad47"),
                    breaks = c("Sulawesi Selatan", "Sulawesi Utara", "Sulawesi Tengah", "Sulawesi Tenggara", "Papua", "Lainnya")) +
  scale_x_continuous(labels = scales::percent_format(scale = 1)) +
  annotate(geom = "text",
           y = seq_len(nrow(data_lainnya)),
           x = -3.5,
           label = data_lainnya$q,
           size = 3) +
  annotate(geom = "text",
           y = c(2.5, 5.5),
           x = -9.5,
           label = unique(data_lainnya$year),
           size = 3,
           angle = '90')

  • Step 6: Merapikan Tampilan Visual
  theme(legend.direction = "horizontal",
        legend.position = "bottom",
        legend.key.size = unit(0.4, 'cm'),
        legend.text = element_text(size=7),
        legend.title = element_blank(),
        axis.text.x = element_text(size=8),
        axis.title.y = element_blank(),
        axis.text.y = element_blank(),
        panel.grid.major.x = element_blank(),
        panel.grid.minor.x = element_blank(),
        panel.grid.major.y = element_blank(),
        panel.grid.minor.y = element_blank(),
        plot.caption = element_text(face="italic", size=6))
ggplot(data = data_g2,
       mapping = aes(y = year_q, x = values)) +
  geom_col(aes(fill = kolom1), width = 0.5) +
  geom_text(aes(label = values),
            fontface = "bold",
            position = position_stack(vjust = 0.5),
            size = 2.5,
            color = "white") +
  scale_fill_manual(values = c("#5b9bd5", "#ed7d31", "#a5a5a5", "#ffc000", "#4472c4", "#70ad47"),
                    breaks = c("Sulawesi Selatan", "Sulawesi Utara", "Sulawesi Tengah", "Sulawesi Tenggara", "Papua", "Lainnya")) +
  scale_x_continuous(labels = scales::percent_format(scale = 1)) +
  annotate(geom = "text",
           y = seq_len(nrow(data_lainnya)),
           x = -3.5,
           label = data_lainnya$q,
           size = 3) +
  annotate(geom = "text",
           y = c(2.5, 5.5),
           x = -9.5,
           label = unique(data_lainnya$year),
           size = 3,
           angle = '90') +
  labs(x = NULL,
       y = NULL, 
       caption = "Sumber: BPS, diolah") +
  theme_minimal() +
    theme(legend.direction = "horizontal",
        legend.position = "bottom",
        legend.key.size = unit(0.4, 'cm'),
        legend.text = element_text(size=7),
        legend.title = element_blank(),
        axis.text.x = element_text(size=8),
        axis.title.y = element_blank(),
        axis.text.y = element_blank(),
        panel.grid.major.x = element_blank(),
        panel.grid.minor.x = element_blank(),
        panel.grid.major.y = element_blank(),
        panel.grid.minor.y = element_blank(),
        plot.caption = element_text(face="italic", size=6))

Variasi barplot ini disebut stacked barplot. Plot ini membantu kita untuk melihat peringkat secara umum dan juga melihat variabel kategoris lainnya untuk setiap level. Sekarang kita mendapatkan wawasan bahwa Sulawesi Selatan memberikan kontribusi terbesar dibandingkan dengan wilayah Sulampua lainnya.

Terkadang, dalam menggunakan multivariate plot kita perlu memperhatikan variasi mana yang digunakan. Sebagai contoh lain, variasi dodge dapat digunakan untuk melihat perbedaan ketinggian dari suatu nilai. Berikut ini mari kita lihat bagaimana visual kita yang sebelumnya dalam bentuk stacked dalam variasi dodge

ggplot(data = data_g2,
       mapping = aes(y = year_q, x = values)) +
  geom_col(aes(fill = kolom1), width = 0.5, position = "dodge") 

1.3.3 Time-based evolution

Time series adalah analisis yang cukup sering digunakan dalam aspek bisnis atau domain teknis lainnya. Analisis deret waktu ini bisa membantu untuk melihat dinamika yang lebih jelas dari nilai numerik dalam hal dimensi waktu.

Pada bagian ini, kita akan membahas cara membuat visualisasi time series dan interpretasinya menggunakan dataset Covid.

  • Step 1: Membaca Data
# data preparation
data_covid_harian <- read_excel("Data/BAB 1.xlsx", sheet = "G 1. 3 COVID", range = cell_cols(1:7))

# data cleaning
data_covid_harian <- data_covid_harian %>% 
  mutate(tgl_laporan = ymd(tgl_laporan))

# print some example
head(data_covid_harian)
  • Step 2: Membuat visual dengan geom_line()
ggplot(data = data_covid_harian, mapping = aes(x=tgl_laporan, y=kasus_harian))+
  geom_line(group=1,col="#0b2b5e")

  • Step 3: Mengatur sumbu X dengan menggunakan fungsi scale_x_date()

Parameter yang dapat digunakan: - date breaks = ...days ... week ...month - date_labels = format tanggal

Contoh: scale_x_date(date_breaks = "1 week", date_labels = "%m-%d")

ggplot(data = data_covid_harian, mapping = aes(x=tgl_laporan, y=kasus_harian))+
  geom_line(group=1,col="#0b2b5e")+
  scale_x_date(labels = date_format("%b %Y"))

  • Step 4: Mengatur sumbu X dengan menggunakan fungsi scale_y_continous()

Parameter yang dapat digunakan: - breaks(seq(..,..,..))

Contoh: scale_y_continuous(breaks = seq(3, 27, 3))

# Please type your code down below
ggplot(data = data_covid_harian, mapping = aes(x=tgl_laporan, y=kasus_harian))+
  geom_line(group=1,col="#0b2b5e")+
  scale_x_date(labels = date_format("%b %Y"))+
  scale_y_continuous(breaks = seq(0,1500,500), labels=scales::comma)

  • Step 5: Tahapan Mempercantik Plot
  labs(x = NULL, y=NULL, caption = "Sumber: Kementerian Kesehatan, diakses melalui Covid19.go.id") +
  theme_minimal() +
  theme(legend.direction = "horizontal",
        legend.position = "bottom",
        axis.text.x = element_text(size = 7),
        axis.text.y = element_text(size = 7),
        legend.title = element_blank(),
        panel.grid.major.x = element_blank(),
        panel.grid.minor.x = element_blank(),
        panel.grid.major.y = element_blank(),
        panel.grid.minor.y = element_blank(),
        plot.caption = element_text(size=5,face = "italic"))
# visualize
ggplot(data = data_covid_harian, mapping = aes(x=tgl_laporan, y=kasus_harian))+
  geom_line(group=1,col="#0b2b5e")+
  scale_x_date(labels = date_format("%b %Y"))+
  scale_y_continuous(limits = c(0,1500),breaks = seq(0,1500,500), labels=scales::comma)+
  labs(x = NULL, y=NULL, caption = "Sumber: Kementerian Kesehatan, diakses melalui Covid19.go.id") +
  theme_minimal() +
  theme(legend.direction = "horizontal",
        legend.position = "bottom",
        axis.text.x = element_text(size = 7),
        axis.text.y = element_text(size = 7),
        legend.title = element_blank(),
        panel.grid.major.x = element_blank(),
        panel.grid.minor.x = element_blank(),
        panel.grid.major.y = element_blank(),
        panel.grid.minor.y = element_blank(),
        plot.caption = element_text(size=5,face = "italic"))

Seperti yang bisa kita lihat dari plot di atas, visualisasi time series dapat dengan mudah memberikan gambaran serta wawasan yang lebih jelas mengenai perkembangan harian kasus terkonfirmasi Covid-19. Untuk interpretasi, kita perlu fokus pada beberapa komponen deret waktu: trend, seasonality, dan shock. Pertama-tama, kita dapat menyimpulkan bahwa deret waktu kita tidak memiliki pola musiman yang signifikan, sehingga kita dapat mengabaikannya. Selain itu, trend kasus cenderung fluktuatif. Terkait shock, kita bisa melihat kasus terkonfirmasi Covid-19 menunjukkan lonjakan signifikan pada Juli-Agustus 2021. Jika kita fokus pada komponen-komponen tersebut, kita dapat mencari penjelasan lebih lanjut mengenai insight dari komponen-komponen tersebut. Misalnya, mencari faktor mengapa terjadi shock kasus terkonfirmasi Covid-19 pada Juli-Agustus 2021.

1.4 Advanced Visualization

1.4.1 Plotting Dual Axis

Plot Dual Axis sangat berguna sekali ketika kita menemui sebuah data yang mempunyai range nilai yang berbeda. Sebagai contoh yang dapat kita lihat pada Grafik 1.21 Laporan Bab I:

  • Produksi perikanan yang memiliki satuan ton
  • Pertumbuhan produksi perikanan dengan satuan persentase year-of-year(%yoy)

Untuk dapat melakukan pengaturan lebih jauh terhadap dual axis, kita dapat mengikuti langkah berikut:

  • Menambahkan axis tambahan pada atas dan bawah frame
  • Mengubah rentang nilai axis
  • Serta kustomisasi tick mark pada nilai axis.

Hal ini diperlukan karena fungsi grafik pada R tidak dapat mengatur axis secara otomatis saat plot baru ditambahkan pada plot pertama dan rentang nilai plot baru lebih besar dibanding plot pertama, sehingga sebagian nilai plot baru tidak ditampilkan pada hasil akhir.

Menggunakan contoh kasus di atas, kita akan membuat visualisasi yang menggambarkan produksi dan pertmbuhan produksi ikan di Sulawesi Selatan.

  • Step 1: Persiapan Data
# data preparation for G1.21
data_g21 <- load_data("Data/BAB 1.xlsx", 
                      sheet_name = "G1. 21 PROD.IKAN", 
                      row_range = 3:15, start_year = 2018)

data_g21 <- data_g21 %>%
  filter(year %in% c("2019","2020", "2021", "2022"), 
         kolom1 %in% c("Produksi (Ton)"))

data_g21.1 <- load_data("Data/BAB 1.xlsx", 
                        sheet_name = "G1. 21 PROD.IKAN (2)", 
                        row_range = 3:15)

data_g21.1 <- data_g21.1 %>%
  filter(year != 2019, kolom1 %in% c("Produksi (%yoy) - rhs"))
  • Step 2: Pembuatan Fungsi Manual

Silahkan perhatikan visualisasi di bawah ini untuk menggambarkan bagaimana kita mengatur dual axis pada plot sesuai dengan contoh kasus di yang telah dibahas sebelumnya:

# setting for dual axis
tmp <- data.frame(
  A = c(0, max(data_g21$values)),
  B = c(min(data_g21.1$values), max(data_g21.1$values))
)

itmod <- lm(A ~ B, data=tmp)
tmod <- lm(B ~ A, data=tmp)

trans <- function(x)coef(tmod)[1] + coef(tmod)[2]*x
invtrans <- function(x)coef(itmod)[1] + coef(itmod)[2]*x
  • Step 3: Pembuatan Visual
# visualization
ggplot(data = data_g21,
       aes(x = year_q, y = values)) +
  geom_col(aes(fill = kolom1), width = 0.7) +
  geom_line(data = data_g21.1,
            aes(y = invtrans(values), # Menentukan value berdasarkan axis 1
                colour = kolom1, 
                group = 1),
            size = 1) +
  scale_y_continuous(limits = c(-400000, 1400000),
                     breaks = seq(0, 1400000, 200000),
                     # Bagian yang mengatur secondary axis
                     sec.axis = sec_axis(trans=trans, 
                                         breaks = seq(-10, 20, 5))) +
  scale_fill_manual(values = "#ED7D31") +
  scale_color_manual(values = "#5B9BD5") 

Penggunaan axis ganda menjadi tantangan tersendiri apabila basis dari kedua nilai yang divisualisasikan tidak sama (contoh: untuk plot di atas basis nilai sumbu y tidak sama-sama dimulai dari 0). Oleh karena itu, penggunaan formula yang tepat juga perlu dipertimbangkan untuk selanjutnya Anda bisa gunakan pada parameter trans pada fungsi sec_axis().

  • Step 4: Merapikan Visual
# visualization
nq <- nrow(data_g21)
mod <- nq %/% 4

ggplot(data = data_g21,
       aes(x = year_q, y = values)) +
  geom_col(aes(fill = kolom1), width = 0.7) +
  geom_line(data = data_g21.1,
            aes(y = invtrans(values), colour = kolom1, group = 1),
            size = 1) +
  scale_y_continuous(limits = c(-400000, 1400000),
                     breaks = seq(0, 1400000, 200000),
                     sec.axis = sec_axis(trans=trans, breaks = seq(-10, 20, 5))) +
  annotate(geom = "text",
           x = seq_len(nrow(data_g21)),
           y = -130000,
           label = data_g21$q,
           size = 3) +
  annotate(geom = "text",
           x = c(2.5, 6.5, 10.5, 13.6),
           y = -250000,
           label = unique(data_g21$year),
           size = 3) +
  annotate(geom = "segment",
           x = 4.5 + 4 *(0:(mod - 1)),
           xend = 4.5 + 4 *(0:(mod - 1)),
           y = -10000,
           yend = -300000,
           col = "grey") +
  labs(x = NULL, y = NULL, caption = "Sumber: Dinas Kelautan dan Perikanan, diolah") +
  scale_fill_manual(values = "#ED7D31") +
  scale_color_manual(values = "#5B9BD5") +
  theme_minimal() +
  theme(legend.direction = "horizontal",
        legend.position = "top",
        legend.spacing.x = unit(0.1, 'cm'),
        legend.key.size = unit(0.3, 'cm'),
        legend.text = element_text(size=8),
        legend.title = element_blank(),
        axis.title.x = element_blank(),
        axis.text.x = element_blank(),
        axis.text.y = element_text(size=8),
        panel.grid.major.x = element_blank(),
        panel.grid.minor.x = element_blank(),
        panel.grid.major.y = element_blank(),
        panel.grid.minor.y = element_blank(),
        plot.caption = element_text(face = "italic", size=7))

Selain itu, Anda mungkin akan menyadari juga pada visualisasi di atas kami telah menambahkan unsur baru berupa garis segment untuk membagi axis x per tahunnya. Untuk membuat garis tersebut, kita dapat memanfaatkan fungsi annotate() dengan pilihan geometri segment dan Anda bisa mengatur posisinya sama halnya seperti Anda mengatur posisi axis text triwulan dan tahun yang sudah dicoba sebelumnya.

1.4.2 Arrange Multiple ggplots

Modifikasi dan pemformatan dasar ggplot membutuhkan pengetahuan sintaksis yang lebih dalam dan keterampilan R yang lebih handal. Namun, ggplot telah mengalami banyak perkembangan untuk melakukan visualisasi yang sangat kompleks, seperti bagaimana melakukan layouting untuk menggabungkan lebih dari satu objek ggplot dalam satu halaman.

Pada bagian ini, kita akan membahas cara membuat banyak plot dan memvisualisasikannya ke dalam satu halaman. Mari kita mulai dengan contoh sederhana: memvisualisasikan pertumbuhan impor dan negara asal impor barang dan jasa.

# data preparation
impor <- load_data("Data/BAB 1.xlsx", sheet = "G1. 16 IMPOR", 3:4)
impor_negara <- read_excel("Data/BAB 1.xlsx",sheet = "G1. 16 IMPOR", range = cell_rows(6:11))

# subsetting
impor_luar <- impor %>% filter(kolom1 %in% "Impor Luar Negeri Non Migas")

# data cleansing
impor_negara$negara <-  as.factor(impor_negara$negara)
impor_negara$ymax <- cumsum(impor_negara$impor)
impor_negara$ymin <- c(0, head(impor_negara$ymax, n=-1))
impor_negara$labelPosition <- (impor_negara$ymax + impor_negara$ymin) / 2
impor_negara$label_name <- impor_negara$impor*100

Sekarang, coba perhatikan visualisasi di bawah ini:

nq <- nrow(impor_luar)
mod <- nq %/% 4

impor_growth <- ggplot(data = impor, mapping = aes(x = year_q, y = values)) +
  geom_hline(yintercept = 0,
             col="#D9D9D9") +
  geom_xspline(aes(y = values, color = kolom1, group=kolom1),
            size=2,
            spline_shape=-0.4,
            show.legend = T)+
  annotate(geom = "text",
           x = seq_len(nrow(impor_luar)),
           y = -60,
           label = impor_luar$q,
           size = 3) +
  annotate(geom = "text",
           x = c(2.5, 6.5, 10.5, 13.6),
           y = -70,
           label = unique(impor_luar$year),
           size = 3) +
  annotate(geom = "segment",
           x = 4.5 + 4 *(0:(mod - 1)),
           xend = 4.5 + 4 *(0:(mod - 1)),
           y = -55,
           yend = -70,
           col = "grey") +
  scale_y_continuous(breaks = seq(-40,40,25))+
  labs(subtitle = "%(yoy)", x = NULL, y = NULL) +
  scale_color_manual(values = c("#c93d16", "#e87f0e")) +
  theme_minimal() +
  theme(legend.direction = "horizontal",
        legend.position = "bottom",
        legend.title = element_blank(),
        legend.text = element_text(size=7),
        axis.title.x = element_blank(),
        axis.text.x = element_blank(),
        panel.grid.major.x = element_blank(),
        panel.grid.minor.x = element_blank(),
        panel.grid.major.y = element_blank(),
        panel.grid.minor.y = element_blank(),
        plot.subtitle = element_text(size=8),
        plot.caption = element_text(size=6))

impor_growth

Seperti yang Anda lihat, kita telah berhasil memvisualisasikan objek ggplot pertama dan menyimpannya di dalam variabel import_growth. Mungkin Anda akan menyadari bahwa kita menggunakan fungsi geometri baru geom_xspline() untuk membuat garis lebih halus. Selanjutnya, mari kita lihat visualisasi kedua di bawah ini:

dou_impor <- ggplot(impor_negara, aes(ymax=ymax, ymin=ymin, xmax=4, xmin=3, fill=negara)) +
  geom_rect() +
  geom_text(x=3.5, aes(y=labelPosition, label=round(label_name,2)), size=4) +
  coord_polar(theta="y") +
  scale_fill_manual(values = c( "#96B9D9", "#FFCC66", "#E19B96", "red", "blue"), name = NULL) +
  guides(fill=guide_legend(nrow=2,byrow=TRUE))+
  xlim(c(2, 4)) +
  theme_void() +
  labs(x=NULL, y=NULL, fill ="", caption = "Sumber: BPS, diolah")+
  theme(legend.position="bottom",
        legend.direction = "horizontal",
        legend.title = element_blank(),
        legend.text = element_text(size=8),
        legend.key.height = unit(0.7, "lines"), #smaller squares
        legend.key.width = unit(0.7, "lines"),
        plot.subtitle = element_text(size=8, vjust = -30),
        plot.margin = unit(c(0,0,0,1), "cm"),
        legend.spacing.y = unit(0.5, 'cm'),
        plot.caption = element_text(face = "italic", size=7))

dou_impor

Kita akan menggunakan fungsi plot_grid() dari library cowplot untuk menggabungkan plot-plot di atas menjadi satu halaman. Fungsi plot_grid() membutuhkan list nama plot kita, kemudian argumen nrow dan ncol memungkinkan kita untuk menentukan jumlah baris dan kolom yang kita inginkan dalam visualisasi nantinya. Selain itu, tidak kalah penting Anda juga bisa mengatur bagaimana orientasi dari peletakan posisi plot dengan menggunakan parameter align.

plot_grid(impor_growth,dou_impor, 
          ncol = 2, 
          rel_widths = c(2, 1.5))

1.4.2.1 Dive Deeper

Terakhir, masih banyak jenis visualisasi yang belum kita eksplor bersama. Sekarang giliran Anda untuk melakukan eksplorasi lebih dalam tentang fungsi geometri di ggplot dan library pendukung lainnya bersama tim Anda untuk menyelesaikan visualisasi dalam laporan Bab 1.

# your code here