email             :
ntraktir          : https://trakteer.id/contekansial
nyawer          : https://saweria.co/contekansial
github            : https://bit.ly/origin-AL-GitHub
youtube         : https://bit.ly/origin-AL-youtube



#Prolog

Bahasa R memiliki berbagai sistem untuk membuat grafik, baik grafik statis maupun grafik interaktif. Pada grafik statis misalnya terdapat sistem base, lattice, ggplot, dan lainnya. Di dalam pembelajaran ini kamu akan diajak untuk mengenal salah satu sistem grafik yang paling populer di R, yaitu ggplot.

Sistem pembuatan grafik dengan ggplot dapat dilakukan dengan menggunakan paket ggplot2 yang merupakan implementasi dari konsep Grammar of Graphic untuk bahasa pemrograman R. Pada prinsipnya, konsep Grammar of Graphic mengajak kita untuk merekonstruksi pembuatan grafik dengan menggunakan kaidah tata bahasa sehingga tidak terikat pada nama jenis grafik (contoh: scatterplot, line-chart, bar-chart, dll.) seperti yang umumnya dilakukan. Taukah kamu bahwa Tableu merupakan salah satu aplikasi/program yang menerapkan konsep tersebut ?

0.1 Konsep Grammar of Graphic

Konsep Grammar of Graphic akan mengasah intuisi kamu untuk membentuk berbagai jenis grafik dengan lebih mudah, ringkas, dan tertata. Kamu dapat membaca artikel mengenai implementasi konsep Grammar of Graphic di ggplot2. Namun sekarang silakan aktifkan paket ggplot2 !

Begini :

#set library yang dibutuhkan
library("ggplot2")

0.2 Mengingat Kembali

Taukah kamu bahwa pada ggplot2 terdapat satu fungsi yang dapat digunakan untuk membuat grafik dengan cepat ? Fungsi tersebut adalah qplot() ! Sesuai dengan namanya, quick plot sangat bermanfaat untuk membuat grafik dengan ringkas dan cepat. Penggunaannya juga lebih mudah bagi yang sudah terbiasa dengan fungsi plot() dari sistem grafik base.

Kamu diminta untuk membuat sebuah grafik dengan menggunakan data diamonds yang tersedia dalam paket ggplot2. Kamu dapat melihat isi serta dokumentasi dari dataset tersebut dengan menjalankan diamonds dan ?diamonds di konsol R (atau klik tautan ini jika untuk dokumentasi daring). Setelah kamu membaca dokumentasi data diamonds tersebut, buatlah grafik hubungan antara berat (sumbu x), harga (sumbu y) dan kejernihan intan!

Begini :

#membuat grafik hubungan antara berat dengan harga
qplot(x = carat, y = price, colour = clarity, data = diamonds)

0.3 Pembuatan Grafik dengan ggplot

Mudah sekali bukan untuk membuat grafik menggunakan qplot() ? Namun sayangnya hal tersebut hanya berlaku untuk grafik-grafik sederhana. Jika kamu ingin membuat grafik yang lebih kompleks dan menawan, maka saatnya kamu beralih menggunakan fungsi ggplot() untuk membuat grafik tersebut.

Lantas bagaimanakah cara untuk menghasilkan grafik serupa namun dengan menggunakan fungsi ggplot() ?

Begini :

#membuat grafik hubungan antara berat dengan harga
ggplot(data = diamonds,
       mapping = aes(x = carat, y = price, colour = clarity)) +
  geom_point()

0.4 Kode 3 Rupa

Salah satu kelebihan dari ggplot2 terletak pada fleksibiltas penulisan kodenya. Perhatikan baris kode yang telah kamu buat sebelumnya !

Begini :

#cara 1 membuat grafik 
diamonds.cara1 <-
  ggplot(
    data = diamonds,
    mapping = aes(x = carat, y = price, colour = clarity)
  ) +
    geom_point()

#melihat hasil cara 1
diamonds.cara1

Kamu dapat menuliskan ulang kode sebelumnya dan menghasilkan grafik yang persis serupa dengan menggunakan cara penulisan lain.

Begini :

library(ggplot2)
#cara 2 membuat grafik
diamonds.cara2 <- 
  ggplot(data = diamonds) +
    geom_point(mapping = aes(x = carat, y = price, colour = clarity))

#melihat hasil cara 2
diamonds.cara2

Begini :

library(ggplot2)
#cara 3 membuat grafik
diamonds.cara3 <- 
  ggplot() +
    geom_point(
      data = diamonds,
      mapping = aes(x = carat, y = price, colour = clarity)
    )

#melihat hasil cara 3
diamonds.cara3

Grafik yang akan dihasilkan oleh tiga cara penulisan tersebut adalah identik. Namun, jika diperhatikan lebih mendalam dengan menggunakan fungsi summary() akan tampak perbedaan diantara ketiganya.

Begini :

#melihat lebih mendalam cara 1
summary(diamonds.cara1)
data: carat, cut, color, clarity, depth, table, price, x, y, z
  [53940x10]
mapping:  x = ~carat, y = ~price, colour = ~clarity
faceting: <ggproto object: Class FacetNull, Facet, gg>
    compute_layout: function
    draw_back: function
    draw_front: function
    draw_labels: function
    draw_panels: function
    finish_data: function
    init_scales: function
    map_data: function
    params: list
    setup_data: function
    setup_params: function
    shrink: TRUE
    train_scales: function
    vars: function
    super:  <ggproto object: Class FacetNull, Facet, gg>
-----------------------------------
geom_point: na.rm = FALSE
stat_identity: na.rm = FALSE
position_identity 
#melihat lebih mendalam cara 2
summary(diamonds.cara2)
data: carat, cut, color, clarity, depth, table, price, x, y, z
  [53940x10]
faceting: <ggproto object: Class FacetNull, Facet, gg>
    compute_layout: function
    draw_back: function
    draw_front: function
    draw_labels: function
    draw_panels: function
    finish_data: function
    init_scales: function
    map_data: function
    params: list
    setup_data: function
    setup_params: function
    shrink: TRUE
    train_scales: function
    vars: function
    super:  <ggproto object: Class FacetNull, Facet, gg>
-----------------------------------
mapping: x = ~carat, y = ~price, colour = ~clarity 
geom_point: na.rm = FALSE
stat_identity: na.rm = FALSE
position_identity 
#melihat lebih mendalam cara 3
summary(diamonds.cara3)
data: [x]
faceting: <ggproto object: Class FacetNull, Facet, gg>
    compute_layout: function
    draw_back: function
    draw_front: function
    draw_labels: function
    draw_panels: function
    finish_data: function
    init_scales: function
    map_data: function
    params: list
    setup_data: function
    setup_params: function
    shrink: TRUE
    train_scales: function
    vars: function
    super:  <ggproto object: Class FacetNull, Facet, gg>
-----------------------------------
mapping: x = ~carat, y = ~price, colour = ~clarity 
geom_point: na.rm = FALSE
stat_identity: na.rm = FALSE
position_identity 

0.5 Komponen Dasar Pembuatan Grafik

Selamat, kamu telah berhasil membuat grafik dengan menggunakan fungsi qplot() dan ggplot(). Setelah menuliskan dan menjalankan beberapa kode sebelumnya, kamu mungkin menyadari bahwa setidaknya terdapat tiga komponen dasar dalam pembuatan grafik yaitu:

  1. Data, yaitu data berisi informasi yang akan dibuat grafik
  2. Mapping, yaitu penentuan variabel/kolom yang akan ditampilkan dalam grafik
  3. Geometries, yaitu representasi visual dari variabel/kolom dalam grafik

Kode pembuatan grafik menggunakan ggplot2() dapat disederhanakan dalam bentuk yang lebih umum. Misalnya penulisan kode untuk membuat grafik menggunakan fungsi qplot() dapat digeneralisasi sebagai berikut:

qplot(<MAPPING>, data = <DATA>, geom = <GEOM>)

Sedangkan untuk fungsi ggplot(), penulisan kode dapat digeneralisasi dalam tiga bentuk sebagai berikut:

Cara 1

ggplot(data = <DATA>, mapping = aes(<MAPPINGS>)) +
  <GEOM_FUNCTION>()  

Cara 2

ggplot(data = <DATA>) +
  <GEOM_FUNCTION>(mapping = aes(<MAPPINGS>))  

Cara 3

ggplot() +
  <GEOM_FUNCTION>(data = <DATA>, mapping = aes(<MAPPINGS>)

0.6 8 Komponen dalam Grafik

Selain tiga komponen dasar yang sebelumnya telah disinggung, dalam konsep Grammar of Graphic terdapat lima komponen utama lainnya yang berperan penting dalam pembuatan sebuah grafik. Berikut merupakan delapan komponen dalam grafik:

  1. Data
  2. Mapping
  3. Statistic
  4. Scales
  5. Geometries
  6. Facets
  7. Coordinates
  8. Theme

Cukup banyak bukan? Dalam pembelajaran ini kamu akan diajak untuk mengenal komponen-komponen dengan lebih dekat. Apakah kamu bersemangat ?

0.7 Yin dan Yang

Namun tunggu dulu ! Sebelum menyelam dalam visualisasi, ada baiknya kita membahas suatu aktivitas yang sulit dilepaskan dari proses pembuatan grafik. Aktivitas tersebut adalah transformasi data !

Seringkali kita harus menyesuaikan bentuk dari data yang kita miliki agar dapat lebih mudah mewujudkannya dalam sebuah grafik. Ya, transformasi dan visualisasi merupakan komplementer satu sama lain. Jika kamu ingin menguasai visualisasi data, maka alangkah baiknya kamu juga memahami proses transformasi data.

Di R, salah satu kumpulan paket yang populer digunakan untuk melakukan transformasi dan visualisasi data adalah tidyverse. Jika ggplot2 berperan utama dalam hal visualisasi data, maka paket yang berperan utama dalam hal transformasi data adalah dplyr dan tidyr. ggplot2 bersama dengan dplyr serta tidyr, readr, tibble, stringr, forcats, dan purrr merupakan paket utama dalam tidyverse.

Sekarang aktifkanlah paket dplyr !

Begini :

#set library yang dibutuhkan
library("dplyr")

0.8 Paket dplyr

Terdapat beberapa fungsi utama dari paket dplyr untuk melakukan transformasi data, diantaranya:

  • select()
  • filter()
  • arrange()
  • mutate()
  • summarise()
  • group_by()

Bacalah dokumentasi masing-masing fungsi di atas dengan cara menjalankan help(nama_fungsi) atau ?nama_fungsi pada konsol R. Atau kamu dapat mengunjungi laman dokumentasi daring dplyr melalui tautan ini.

Note : fungsi select() dan filter() dari paket dplyr sama dengan fungsi subset() dari paket base

0.9 Transformasi Data

Transformasi data umumnya merupakan sebuah rangkaian yang terdiri lebih dari satu proses. Oleh karena itu, dalam tranformasi data menggunakan dplyr sering digunakan operator pipe (%>%) untuk menghubungkan antara satu fungsi ke fungsi selanjutnya. Sebagai ilustrasi, kamu akan diminta untuk melakukan transformasi data storms (dari paket dplyr) dengan dan tanpa menggunakan operator pipe.

Begini :

#set library yang digunakan
library("dplyr")

#melihat data
glimpse(storms)
Rows: 19,066
Columns: 13
$ name                         <chr> "Amy", "Amy", "Amy", "Amy", "Amy", "Amy",…
$ year                         <dbl> 1975, 1975, 1975, 1975, 1975, 1975, 1975,…
$ month                        <dbl> 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,…
$ day                          <int> 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 2…
$ hour                         <dbl> 0, 6, 12, 18, 0, 6, 12, 18, 0, 6, 12, 18,…
$ lat                          <dbl> 27.5, 28.5, 29.5, 30.5, 31.5, 32.4, 33.3,…
$ long                         <dbl> -79.0, -79.0, -79.0, -79.0, -78.8, -78.7,…
$ status                       <fct> tropical depression, tropical depression,…
$ category                     <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
$ wind                         <int> 25, 25, 25, 25, 25, 25, 25, 30, 35, 40, 4…
$ pressure                     <int> 1013, 1013, 1013, 1013, 1012, 1012, 1011,…
$ tropicalstorm_force_diameter <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
$ hurricane_force_diameter     <int> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
#tanpa menggunakan pipe
storms1 <- select(storms, year, month, wind, pressure)
storms2 <- filter(storms1, between(year, 2000, 2015))
storms3 <- mutate(storms2, month = factor(month.name[storms2$month], levels = month.name))
storms4 <- group_by(storms3, month)
storms.tanpa.pipe <- summarise(storms4, avg_wind = mean(wind), avg_pressure = mean(pressure))
glimpse(storms.tanpa.pipe)
Rows: 10
Columns: 3
$ month        <fct> January, April, May, June, July, August, September, Octob…
$ avg_wind     <dbl> 41.96429, 38.46154, 34.60000, 35.15942, 44.26450, 47.4416…
$ avg_pressure <dbl> 1001.6786, 1001.6410, 1004.5600, 1000.5101, 999.5007, 996…
#menggunakan pipe
storms.pipe <-
  storms %>%
  select(year, month, wind, pressure) %>%
  filter(between(year, 2000, 2015)) %>%
  mutate(month = factor(month.name[month], levels = month.name)) %>%
  group_by(month) %>%
  summarise(
    avg_wind = mean(wind),
    avg_pressure = mean(pressure)
  )
glimpse(storms.pipe)
Rows: 10
Columns: 3
$ month        <fct> January, April, May, June, July, August, September, Octob…
$ avg_wind     <dbl> 41.96429, 38.46154, 34.60000, 35.15942, 44.26450, 47.4416…
$ avg_pressure <dbl> 1001.6786, 1001.6410, 1004.5600, 1000.5101, 999.5007, 996…
#komparasi metode tanpa pipe dan dengan pipe
identical(storms.tanpa.pipe, storms.pipe)
[1] TRUE

1 INDO-DAPOER

1.1 Tentang Data

Mari kita mulai! Sekarang kamu akan ditantang untuk melakukan eksplorasi dan visualisasi data INDO-DAPOER, yaitu akronim dari Indonesia Database for Policy and Economic Research. Data tersebut disediakan oleh The World Bank dan tersedia dalam pranala [ini](https://datacatalog.worldbank.org/search/dataset/0041056.

Singkatnya, INDO-DAPOER merupakan data yang berisikan indikator ekonomi dan sosial pada level provinsi serta kota/kabupaten di Indonesia. Ada empat kategori utama yang terhimpun di dalam data ini, yaitu: fiskal, ekonomi, sosial-demografi, serta infrastuktur.

Menarik sekali bukan?

1.2 Import Dataset

Di dalam pembelajaran ini dataset INDO-DAPOER disediakan dalam bentuk yang telah disederhanakan dan dikompresi dikarenakan ukurannya yang relatif besar. kamu akan memerlukan paket readr untuk mengimpor berkas indodapoer.tsv.gz yang telah disediakan. Pergunakan fungsi read_tsv() dan simpanlah hasilnya ke dalam obyek R bernama indo.dapoer ! Berapakah jumlah baris dan kolom dari data tersebut ?

Begini :

#set library yang dibutuhkan
library("readr")

#membuat variabel dataset
indo.dapoer <- read_tsv("https://storage.googleapis.com/dqlab-dataset/indodapoer.tsv.gz", show_col_types = FALSE)

#melihat jumlah baris
nrow(indo.dapoer)
[1] 22468
#melihat jumlah kolom
ncol(indo.dapoer)
[1] 222

1.3 Wild Names and How to Tame Them

Ya! Data indodapoer memiliki 22468 baris dan 222 kolom. Data yang cukup kompleks bukan ?

Jika kamu perhatikan nama-nama kolom tersebut, masih banyak yang tidak memenuhi kaidah syntactically valid names di R (tips: silakan baca dokumentasi fungsi make.names()). Silakan kamu periksa nama 15 kolom pertama menggunakan colnames(), kemudian jalankan clean_names() dari paket janitor untuk menangani permasalahan nama kolom tersebut dan simpan hasilnya sebagai indo.dapoer. Selanjutnya periksa kembali nama 15 kolom pertama dari data yang telah diproses tersebut !

Begini :

#set library yang dibutuhkan
library("janitor")

#melihat 15 kolom pertama
head(colnames(indo.dapoer), 15)
 [1] "area_name"                                                                                                  
 [2] "year"                                                                                                       
 [3] "Agriculture function expenditure (in IDR)"                                                                  
 [4] "Average National Exam Score: Junior Secondary Level (out of 100, available only in district level for 2009)"
 [5] "Average National Exam Score: Primary Level (out of 100, available only in district level for 2009)"         
 [6] "Average National Exam Score: Senior Secondary Level (out of 100, available only in district level for 2009)"
 [7] "Birth attended by Skilled Health worker (in % of total birth)"                                              
 [8] "BPK Audit Report on Sub-National Budget"                                                                    
 [9] "Capital expenditure (in IDR)"                                                                               
[10] "Consumer Price Index in 42 cities base 1996"                                                                
[11] "Consumer Price Index in 45 cities base 2002"                                                                
[12] "Consumer Price Index in 66 cities base 2007"                                                                
[13] "Economy function expenditure (in IDR)"                                                                      
[14] "Education function expenditure (in IDR)"                                                                    
[15] "Environment function expenditure (in IDR)"                                                                  
#menangani permasalahan kolom
indo.dapoer <- clean_names(indo.dapoer)

#melihat kembali 15 kolom
head(colnames(indo.dapoer), 15)
 [1] "area_name"                                                                                              
 [2] "year"                                                                                                   
 [3] "agriculture_function_expenditure_in_idr"                                                                
 [4] "average_national_exam_score_junior_secondary_level_out_of_100_available_only_in_district_level_for_2009"
 [5] "average_national_exam_score_primary_level_out_of_100_available_only_in_district_level_for_2009"         
 [6] "average_national_exam_score_senior_secondary_level_out_of_100_available_only_in_district_level_for_2009"
 [7] "birth_attended_by_skilled_health_worker_in_percent_of_total_birth"                                      
 [8] "bpk_audit_report_on_sub_national_budget"                                                                
 [9] "capital_expenditure_in_idr"                                                                             
[10] "consumer_price_index_in_42_cities_base_1996"                                                            
[11] "consumer_price_index_in_45_cities_base_2002"                                                            
[12] "consumer_price_index_in_66_cities_base_2007"                                                            
[13] "economy_function_expenditure_in_idr"                                                                    
[14] "education_function_expenditure_in_idr"                                                                  
[15] "environment_function_expenditure_in_idr"                                                                

1.4 Mudah bukan ?

Dengan satu fungsi clean_names(), kamu dapat merapikan nama-nama kolom sehingga akan lebih mudah digunakan untuk analisis atau visualisasi data.


2 Indonesia Negeriku

2.1 Produk Domestik Regional Bruto

Kamu tertarik untuk melihat perkembangan Produk Domestik Regional Bruto (PDRB) Non-Migas dari provinsi-provinsi di pulau Jawa. Informasi PDRB Non-Migas tersebut tersimpan pada kolom total_gdp_excluding_oil_and_gas_in_idr_million_constant_price. Sebelum memulai membuat visualisasi, ekstraklah data tersebut menjadi PDRB.Jawa !

Begini :

#set library yang dibutuhkan
library("stringr")
library("dplyr")

#mengekstrak data
PDRB.Jawa <- indo.dapoer %>%
  filter(
    area_name %in% c(
      "Banten, Prop.",
      "DKI Jakarta, Prop.",
      "Jawa Barat, Prop.",
      "Jawa Tengah, Prop.",
      "DI Yogyakarta, Prop.",
      "Jawa Timur, Prop."
    )
  ) %>%
  transmute(
    provinsi = str_remove(area_name, ", Prop."),
    tahun = year,
    pdrb_nonmigas = total_gdp_excluding_oil_and_gas_in_idr_million_constant_price) %>% 
    filter(!is.na(pdrb_nonmigas))

#melihat hasil
glimpse(PDRB.Jawa)
Rows: 164
Columns: 3
$ provinsi      <chr> "Banten", "Banten", "Banten", "Banten", "Banten", "Bante…
$ tahun         <dbl> 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 20…
$ pdrb_nonmigas <dbl> 45690559, 47495383, 49449321, 51957458, 54880407, 581069…

2.2 Grafik PDRB Non-Migas

Dengan menggunakan data PDRB.Jawa kita akan membuat grafik tren PDRB Non-Migas.

Begini :

ggplot(
  PDRB.Jawa,
  aes(tahun, pdrb_nonmigas, colour = provinsi)
) +
  geom_line()

Apakah kamu menemukan kejanggalan pada grafik tersebut ? Ya ! Urutan nama provinsi pada legenda tidak mempresentasikan urutan yang ditampilkan pada grafik. Bayangkan jika kamu memiliki lebih banyak nama provinsi yang ditampilkan pada grafik, akan sulit untuk dapat mencocokan nama pada legenda dan garis pada grafik. Solusi pertama yang dapat kamu lakukan adalah dengan cara mengurutkan nama provinsi berdasarkan besaran PDRB Non-Migas pada tahun terakhir. Bagaimanakah caranya ?

Begini :

#set library yang dibutuhkan
library(ggplot2)
library("dplyr")
library("forcats")

#membuat grafik
PDRB.Jawa %>%
  mutate(
    provinsi = fct_reorder2(provinsi, tahun, pdrb_nonmigas)
  ) %>%
  ggplot(aes(tahun, pdrb_nonmigas, colour = provinsi)) +
  geom_line()

2.3 Direct Labeling

Solusi kedua untuk mengatasi permasalahan pada grafik sebelumnya dalah dengan menggunakan direct labeling. Hal ini lebih direkomendasikan karena salah satu prinsip dalam merancang grafik adalah “sebisa mungkin rancang grafik yang tidak memerlukan legenda”. Kamu dapat memanfaatkan fungsi geom_dl() dari paket directlabels untuk membuat direct labeling di ggplot2. Adapun aesthetic mapping yang diperlukan dalam geom_dl() tersebut adalah label. Sekarang buatlah grafik serupa namun menggunakan direct labeling ! Serta jangan lupa untuk menghapus legenda nama provinsi dengan cara menambahkan argumen show.legend = FALSE pada geom_line().

Begini :

#set library yang dibutuhkan
library(ggplot2)
library("dplyr")
library(directlabels)

#membuat grafik
PDRB.Jawa %>%
  ggplot(aes(tahun, pdrb_nonmigas)) +
  geom_line(aes(colour = provinsi), show.legend = FALSE) +
  geom_dl(
    aes(label = provinsi), 
    method = "last.points",
    position = position_nudge(x = 0.3) # agar teks tidak berhimpitan dengan garis
  )

2.4 Finalisasi Grafik

Selamat, kamu telah berhasil membuat grafik menggunakan direct labeling ! Selain itu, apakah kamu menyadari bahwa pada beberapa kode sebelumnya suatu data (tanpa atau dengan transformasi) langsung diarahkan ke ggplot() dengan menggunakan operator pipe (%>%) ? Fitur tersebut tentu sangat mempermudah dalam aktivitas transformasi dan visualisasi data, apakah kamu setuju ?

Sekarang saatnya kamu melakukan finalisasi untuk grafik yang telah dibuat. Ada beberapa hal yang harus kamu lakukan, termasuk memperbaiki teks nama provinsi yang terpotong pada kanvas. Jalankanlah langkah-langkah di bawah ini !

  • Bagi pdrb_nonmigas dengan 1e6 (satu juta), sehingga staun pdrb_nonmigas sekarang adalah dalam triliun
  • Tambahkan label pada grafik menggunakan fungsi labs(). Beri label sebagai berikut:
    • Judul: “PDRB Non-Migas di Pulau Jawa Hingga Tahun 2011”
    • Subjudul: “PDRB atas dasar harga konstan, dalam satuan triliun”
    • Sumbu x: (tidak ada label)
    • Sumbu y: (tidak ada label)
    • Caption: “Data: INDO-DAPOER, The World Bank”
  • Non-aktifkan clipping pada kanvas dengan mengatur argumen clip = "off" pada coord_cartesian() [Catatan: cara ini terkadang perlu dikombinasikan dengan argumen expand pada scale_x/y_***()]
  • Pergunakan theme_ipsum() dari paket hrbrthemes untuk memodifikasi tema

Begini :

#set library yang dibutuhkan
library(ggplot2)
library("dplyr")
library(directlabels)
library("hrbrthemes")

#membuat grafik
PDRB.Jawa %>%
  ggplot(aes(tahun, pdrb_nonmigas / 1e6)) +
  geom_line(aes(colour = provinsi), show.legend = FALSE) +
  geom_dl(
    aes(label = provinsi), 
    method = "last.points",
    position = position_nudge(x = 0.3) # agar teks tidak berhimpitan dengan garis
  ) +
  labs(
    x = NULL,
    y = NULL,
    title = "PDRB Non-Migas di Pulau Jawa Hingga Tahun 2011",
    subtitle = "PDRB atas dasar harga konstan, dalam satuan triliun",
    caption = "Data: INDO-DAPOER, The World Bank"
  ) +
  coord_cartesian(clip = "off") +
  theme_ipsum(grid = "Y", ticks = TRUE)

2.5 Seluas Apa ?

Indonesia merupakan negara kepulauan yang sangat luas, tentu kamu telah mengetahui akan hal tersebut. Namun bagaimanakah perbandingan luas provinsi-provinsi di Indonesia ?

Dalam data indo.dapoer, data luas wilayah tersedia dalam kolom total_area_in_km2. Data termutakhir adalah pada tahun 2009. Dapatkah kamu mengekstrak data tersebut menjadi obyek R bernama Luas.Prov ?

Begini :

Luas.Prov <- indo.dapoer %>%
  filter(str_detect(area_name, "Prop")) %>% 
  filter(year == 2009) %>%
  transmute(
    provinsi = str_remove(area_name, ", Prop."),
    luas_wilayah = total_area_in_km2
  )

glimpse(Luas.Prov)
Rows: 34
Columns: 2
$ provinsi     <chr> "Nanggroe Aceh Darussalam", "Bali", "Kepulauan Bangka-Bel…
$ luas_wilayah <dbl> 57956.00, 5780.06, 16424.06, 19919.33, 9662.92, 11257.07,…

2.6 Komparasi Luas Wilayah

Selanjutnya kamu ditantang untuk membuat komparasi luas wilayah antar provinsi tersebut dalam sebuah grafik bernama treemap. Apakah sebelumnya kamu pernah membuat grafik ini ?

Kamu dapat menggunakan fungsi geom_treemap() dari treemapify untuk membuat grafik tersebut. Aesthetic mapping wajib dalam geom_treemap() tersebut adalah area. Selain itu, untuk menambahkan teks label kamu perlu menggunakan geometry object khusus, yaitu geom_treemap_text(). Apakah kamu ingat apa aesthetic mapping wajib jika ingin menuliskan teks ? Dengan menggunakan data Luas.Prov dapatkah kamu membuat grafik tersebut ?

Begini :

#set library yang dibutuhkan
library(treemapify)

#membuat grafik
Luas.Prov %>%
  ggplot(aes(area = luas_wilayah)) +
  geom_treemap() +
  geom_treemap_text(aes(label = provinsi))

2.7 Modifikasi Grafik

Luar biasa ! Kamu telah berhasil membuat grafik dasar dari treemap luas provinsi ! Sekarang mari lakukan beberapa modifikasi untuk mempercantik tampilan grafik tersebut:

  • Menambahkan luas_wilayah sebagai aesthetic mapping warna kotak
  • Menggunakan palet warna viridis untuk menyatakan luas_wilayah
  • Mengatur posisi, ukuran, dan label pada legenda petunjuk gradasi warna. Kamu akan memerlukan fungsi label_number() dari paket scales
  • Mengganti fonta nama provinsi menjadi “Arial Narrow”, warna menjadi putih, dan konfigurasi ukuran fonta dinamis
  • Menambahkan judul, subjudul, dan caption
  • Mengganti tema plot meenggunakan theme_ipsum() dari paket hrbrthemes

Begini :

#set library yang dibutuhkan
library(ggplot2)
library(hrbrthemes)
library(dplyr)
library(treemapify)
library("scales")

#membuat grafik
Luas.Prov %>%
  ggplot(aes(
    area = luas_wilayah, 
    fill = luas_wilayah)
  ) +
  geom_treemap() +
  geom_treemap_text(
    aes(label = provinsi), 
    family = "Arial Narrow",
    colour = "white",
    reflow = TRUE,
    grow = TRUE
  ) +
  scale_fill_viridis_c(
    guide = guide_colourbar(
      barwidth = 30,
      barheight = 0.8
    ),
    labels = label_number(
      big.mark = ".", 
      decimal.mark = ",", 
      suffix = " km2")
  ) +
  labs(
    fill = "Luas\nwilayah",
    title = "Perbandingan Luas 33 Provinsi di Indonesia",
    subtitle = "Berdasarkan data tahun 2009, sehingga Kalimantan Utara tidak tercantum dalam grafik",
    caption = "Data: INDO-DAPOER, The World Bank"
  ) +
  theme_ipsum() +
  theme(legend.position = "bottom")

2.8 Perjalanan Ini

Menarik bukan ? Pembuatan kode di ggplot() sangat fleksibel dan ada banyak konfigurasi grafik yang dapat dilakukan didalamnya. Nah, seperti telah disinggung sebelumnya bahwasanya dalam membuat visualisasi seringkali ada aktivitas lain yang juga tak kalah penting. Apakah kamu masih ingat apa itu ? Transformasi data !

Pada pembelajaran ini, kamu akan banyak melakukan proses transformasi data sebelum akhirnya membuat visualisasi yang menarik. Kamu diminta untuk mengamati kondisi infrastruktur jalan raya di seluruh kabupatan dan kota di Indonesia. Menarik bukan ?

Begini :

#set library yang dibutuhkan
library(stringr)

#membuat data jalan.kabkota
jalan.kabkota <- indo.dapoer %>%
  filter(str_detect(area_name, ", Prop.", negate = TRUE)) %>% 
  filter(year == 2008) %>%
  transmute(
    kabkota = area_name,
    jalan_rusak_parah = length_of_district_road_bad_damage_in_km_bina_marga_data,
    jalan_rusak_ringan = length_of_district_road_light_damage_in_km_bina_marga_data,
    jalan_cukup_baik = length_of_district_road_fair_in_km_bina_marga_data,
    jalan_sangat_baik = length_of_district_road_good_in_km_bina_marga_data)

#melihat hasil
glimpse(jalan.kabkota)
Rows: 514
Columns: 5
$ kabkota            <chr> "Aceh Barat, Kab.", "Aceh Barat Daya, Kab.", "Aceh …
$ jalan_rusak_parah  <dbl> 64, 1, 97, 112, 21, NA, 130, 8, 168, 76, 25, NA, 39…
$ jalan_rusak_ringan <dbl> 191, 15, 101, 321, 36, 553, 183, 207, 174, 35, 708,…
$ jalan_cukup_baik   <dbl> 218, 81, 270, 416, 59, 170, 146, 284, 201, 74, 333,…
$ jalan_sangat_baik  <dbl> 153, 87, 105, 284, 89, 25, 177, 432, 177, 221, 339,…

2.9 Pivot

Selanjutnya kamu diminta untuk melakukan pivot pada data jalan.kabkota tersebut sehingga menghasilkan sebuah dataframe dengan tiga kolom, yaitu: kabkota, kondisi, dan panjang_jalan. Kamu dapat melakukan hal tersebut dengan menggunakan fungsi pivot_longer() dari paket tidyr.

Begini :

#set library yang dibutuhkan
library(tidyr)

#membuat dataframe
jalan.kabkota <- 
  jalan.kabkota %>% 
  pivot_longer(
    cols = starts_with("jalan_"),
    names_to = "kondisi",
    names_prefix = "jalan_",
    values_to = "panjang_jalan"
  )

#melihat hasil
glimpse(jalan.kabkota)
Rows: 2,056
Columns: 3
$ kabkota       <chr> "Aceh Barat, Kab.", "Aceh Barat, Kab.", "Aceh Barat, Kab…
$ kondisi       <chr> "rusak_parah", "rusak_ringan", "cukup_baik", "sangat_bai…
$ panjang_jalan <dbl> 64, 191, 218, 153, 1, 15, 81, 87, 97, 101, 270, 105, 112…

2.10 The Next Step

Luar biasa ! Namun, masih ada dua tahap yang masih perlu kamu lakukan:

  • Menentukan mana wilayah kabupaten dan mana wilayah kota
  • Mengatur level dari kolom kondisi berdasarkan tingkat keparahan sekaligus memperbaiki penulisan teks agar dapat ditampilkan lebih rapi di dalam grafik

Begini :

#merapikan data
jalan.kabkota <-
  jalan.kabkota %>%
  mutate(
    status = case_when(
      str_detect(kabkota, ", Kab") ~ "Kabupaten",
      str_detect(kabkota, ", Kota") ~ "Kota",
      str_detect(kabkota, "City") ~ "Kota",
      TRUE ~ NA_character_
    ),
    kondisi = factor(
      kondisi,
      levels = c("rusak_parah", "rusak_ringan", "cukup_baik", "sangat_baik"),
      labels = c("Rusak parah", "Rusak ringan", "Cukup baik", "Sangat baik")
    )
  )

#melihat hasil
glimpse(jalan.kabkota)
Rows: 2,056
Columns: 4
$ kabkota       <chr> "Aceh Barat, Kab.", "Aceh Barat, Kab.", "Aceh Barat, Kab…
$ kondisi       <fct> Rusak parah, Rusak ringan, Cukup baik, Sangat baik, Rusa…
$ panjang_jalan <dbl> 64, 191, 218, 153, 1, 15, 81, 87, 97, 101, 270, 105, 112…
$ status        <chr> "Kabupaten", "Kabupaten", "Kabupaten", "Kabupaten", "Kab…

2.11 Grafik Kondisi Jalan

Akhirnya kamu berhasil melakukan transformasi data ! Proses yang cukup melelahkan bukan ?

Sekarang saatnya kamu membuat grafik yang akan menunjukan kondisi jalan raya di kabupaten & kota berdasarkan kondisinya.

Ridgeline plot ! Itulah nama grafik yang akan kamu buat dengan menggunakan data jalan.kabkota tersebut. Apakah kamu pernah membuat grafik jenis ini ?

Rideline plot sangat bermanfaat untuk menampilkan perubahan distribusi dari suatu variabel numerik. Kamu akan memerlukan paket ggridges untuk membuat grafik ini.

Begini :

#set library yang dibutuhkan
library(ggridges)

#membuat grafik
plot.jalan.kabkota <- 
  jalan.kabkota %>% 
  ggplot(aes(panjang_jalan, kondisi)) +
  facet_wrap(~status) +
  geom_density_ridges_gradient(
    aes(fill = after_stat(x)), 
    show.legend = FALSE
  )

#melihat hasil
plot.jalan.kabkota

2.12 Transformasi Logaritmik

That’s the idea ! Di ridgeline plot kamu dapat melakukan komparasi distribusi jalan kabupaten/kota berdasarkan berdasarkan kondisinya dengan mudah. Namun, dalam grafik tersebut masih ada beberapa hal yang harus diperbaiki. Contohnya adalah transformasi pada sumbu-x untuk menangani permasalahan nilai kecil vs nilai besar serta penambahan teks judul, subjudul, dan caption.

Lakukan transformasi logaritmik basis 10 pada sumbu-x menggunakan fungsi scale_x_continous(). Aturlah argumen trans = "log10" pada fungsi tersebut. Selain itu, kamu diminta untuk menambahkan garis vertikal untuk menandai panjang jalan 100 km. Pergunakanlah fungsi geom_vline() untuk melakukan hal tersebut !

Begini :

#menerapkan transformasi log10
plot.jalan.kabkota <-
  jalan.kabkota %>%
  ggplot(aes(panjang_jalan, kondisi)) +
  facet_wrap(~status) +
  geom_density_ridges_gradient(
    aes(fill = after_stat(x)),
    show.legend = FALSE
  )
plot.jalan.kabkota +
  geom_vline(xintercept = 100, linetype = "dashed", colour = "darkslategray4") +
  scale_x_continuous(trans = "log10")

2.13 Finalisasi

Jauh lebih baik, bukan ? Kamu juga dapat menggunakan scale_x_log10() yang merupakan wrapper dari fungsi scale_x_continuous(trans = "log10"). Ada berbagai transformasi yang dapat kamu lakukan pada axis grafik di ggplot2() dan banyak diantaranya telah tersedia pada paket scales.

Sekarang merupakan tahap finalisasi, yang perlu kamu lakukan pada grafik ridgeline tersebut:

  • Menambahkan scale_fill_viridis_c(option = "magma") untuk modifikasi warna
  • Menambahkan keterangan judul, subjudul, dan caption
  • Judul : “Jalan Kabupaten/Kota Berdasarkan Kondisi”
  • Subjudul : “Berdasarkan data tahun 2008, garis vertikal menunjukan panjang jalan 100 Km”
  • Caption : “Data: INDO-DAPOER, The World Bank”
  • Mengatur argumen grid = FALSE dan ticks = TRUE pada theme_ipsum()

Begini :

#membuat grafik final
plot.jalan.kabkota <-
  jalan.kabkota %>%
  ggplot(aes(panjang_jalan, kondisi)) +
  facet_wrap(~status) +
  geom_density_ridges_gradient(
    aes(fill = after_stat(x)),
    show.legend = FALSE
  )
plot.jalan.kabkota +
  geom_vline(xintercept = 100, linetype = "dashed", colour = "darkslategray4") +
  scale_x_continuous(trans = "log10") +
  scale_fill_viridis_c(option = "magma") +
  labs(
    x = "Panjang jalan (Km)",
    y = NULL,
    title = "Jalan Kabupaten/Kota Berdasarkan Kondisi",
    subtitle = "Berdasarkan data tahun 2008, garis vertikal menunjukan panjang jalan 100 Km",
    caption = "Data: INDO-DAPOER, The World Bank"
  ) +
  theme_ipsum(grid = FALSE, ticks = TRUE)

2.14 Finalisasi Kesehatan di Kalimantan

Bagaimanakah komposisi faskes di pulau Kalimantan ? Nah, sekarang kamu kembali ditantang untuk membuat sebuah grafik unik bernama waffle charts untuk menjawab tersebut. Apakah kamu pernah mengetahui jenis grafik ini ?

Begini :

#set library yang dibutuhkan
library(dplyr)
library(ggplot2)
library(tidyr)
library(stringr)
library(forcats)

#membuat data faskes kalimantan
faskes.kalimantan <-
  indo.dapoer %>%
    filter(str_detect(area_name, "Kalimantan")) %>%
    filter(year == 2011) %>%
    transmute(
      provinsi = str_remove(area_name, ", Prop."),
      rumahsakit = number_of_hospitals,
      polindes = number_of_polindes_poliklinik_desa_village_polyclinic,
      puskesmas = number_of_puskesmas_and_its_line_services
    ) %>%
    pivot_longer(
      cols = -provinsi,
      names_to = "faskes",
      values_to = "jumlah"
    ) %>%
    filter(!is.na(jumlah)) %>%
    mutate(
      provinsi = fct_reorder(provinsi, jumlah, sum),
      jumlah = ceiling(jumlah / 10)
    )

#melihat hasil
glimpse(faskes.kalimantan)
Rows: 12
Columns: 3
$ provinsi <fct> Kalimantan Barat, Kalimantan Barat, Kalimantan Barat, Kaliman…
$ faskes   <chr> "rumahsakit", "polindes", "puskesmas", "rumahsakit", "polinde…
$ jumlah   <dbl> 4, 53, 98, 5, 11, 96, 3, 41, 75, 2, 22, 109

2.15 Waffle Charts

Waffle charts dapat dibuat di ggplot2 dengan menggunakan bantuan paket waffle. geom_waffle() yang memiliki dua aesthetic mappings wajib, yakni fill dan values, merupakan fungsi utama dalam pembuatan jenis grafik tersebut. Sekarang buatlah basis grafik tersebut dengan menggunakan data faskes.kalimantan yang telah kamu siapkan !

Penuhilah ketentuan berikut:

  • faskes sebagai aesthetic mapping warna fill
  • provinsi sebagai argumen dalam facet_wrap()
  • simpan hasilnya sebagai plot.faskes.kalimantan

Begini :

#set library yang dibutuhkan
library(waffle)
library("ggplot2")
library(dplyr)

#membuat grafik
plot.faskes.kalimantan <- faskes.kalimantan %>%
  ggplot(aes(fill = faskes, values = jumlah)) +
  facet_wrap(~provinsi) +
  geom_waffle(colors = "white")

#melihat hasil
plot.faskes.kalimantan

2.16 Mengatur Warna dan Label

Selamat, kamu telah berhasil membuat basis grafik yang diminta ! Kamu dapat melakukan kostumisasi warna sesuai dengan keinginan dengan menggunakan fungsi scale_fill_manual() atau scale_colour_manual() jika aesthetic mapping warna yang digunakan adalah colour. Selain itu, kamu juga dapat melakukan modifikasi teks label langsung pada fungsi tersebut dengan mengatur argumen labels (apakah kamu masih ingat pada pembelajaran sebelumnya hal tersebut dilakukan pada fungsi factor() dan mutate() ?).

Sekarang aturlah warna dan label dengan ketentuan sebagai berikut:

  • polindes = “seagreen3”. Ubah label teks menjadi “Poliklinik Desa”
  • puskesmas = “steelblue”. Ubah label teks menjadi “Puskesmas”
  • rumahsakit = “cyan4”. Ubah label teks menjadi “Rumah Sakit”

Begini :

#mengatur warna dan label
plot.faskes.kalimantan <-
  faskes.kalimantan %>%
  ggplot(aes(fill = faskes, values = jumlah)) +
  facet_wrap(~provinsi) +
  geom_waffle(colour = "white")
  
plot.faskes.kalimantan <- 
  plot.faskes.kalimantan +
  scale_fill_manual(
    values = c(
      "polindes" = "seagreen3",
      "puskesmas" = "steelblue",
      "rumahsakit" = "cyan4"
    ),
    labels = c(
      "polindes" = "Poliklinik Desa",
      "puskesmas" = "Puskesmas",
      "rumahsakit" = "Rumah Sakit"
    )
  ) +
  labs(
    fill = NULL,
    title = "Fasilitas Kesehatan di Kalimantan",
    subtitle = "Berdasarkan data tahun 2011, satu petak menyatakan ±10 faskes",
    caption = "Data: INDO-DAPOER, The World Bank"
  )

#melihat hasil
plot.faskes.kalimantan

2.17 Finalisasi Waffle Charts

Luar biasa ! Kamu telah berhasil melakukan modifikasi warna sesuai dengan keinginan. Melalui teknik tersebut, Kamu dapat menuangkan warna branding pada grafik sehingga menjadi produk yang memiliki jati diri kamu.

Hampir selesai ! Ada dua tahap terakhir yang dapat kamu lakukan untuk menyelesaikan waffle chart plot.faskes.kalimantan.

  • Pertama, memastikan agar aspect ratio antara sumbu-x dan sumbu-y adalah 1:1.
  • Kedua, membuat kustomisasi tema grafik.

Permasalahan pertama dapat kamu selesaikan dengan cara menambahkan fungsi coord_equal(). Sedangkan permasalahan kedua dapat diselesaikan dengan fungsi theme(). Jika pada grafik-grafik sebelumnya kamu menggunakan theme_ipsum() yang berasal dari hrbrthemes(), maka kali ini kamu akan membuat sendiri tema sendiri. Keren, kan ? Cobalah kamu atur font dengan menggunakan family = "Arial Narrow" !

Begini :

#melakukan modifikasi grafik
plot.faskes.kalimantan <-
  faskes.kalimantan %>%
  ggplot(aes(fill = faskes, values = jumlah)) +
  facet_wrap(~provinsi) +
  geom_waffle(colour = "white")

plot.faskes.kalimantan <-
  plot.faskes.kalimantan +
  scale_fill_manual(
    values = c(
      "polindes" = "seagreen3",
      "puskesmas" = "steelblue",
      "rumahsakit" = "cyan4"
    ),
    labels = c(
      "polindes" = "Poliklinik Desa",
      "puskesmas" = "Puskesmas",
      "rumahsakit" = "Rumah Sakit"
    )
  ) +
  labs(
    fill = NULL,
    title = "Fasilitas Kesehatan di Kalimantan",
    subtitle = "Berdasarkan data tahun 2011, satu petak menyatakan ±10 faskes",
    caption = "Data: INDO-DAPOER, The World Bank"
  )
  
plot.faskes.kalimantan +
  coord_equal() +
  theme(
    text = element_text(family = "Arial Narrow"),
    plot.title.position = "plot",
    plot.title = element_text(face = "bold", size = 18, hjust = 0.5),
    plot.subtitle = element_text(face = "plain", size = 12, hjust = 0.5),
    plot.caption = element_text(face = "italic", size = 9),
    legend.position = "bottom",
    panel.background = element_blank(),
    panel.grid = element_blank(),
    strip.background = element_blank(),
    strip.text = element_text(face = "italic", size = 9, hjust = 0),
    axis.text.x = element_blank(),
    axis.text.y = element_blank(),
    axis.ticks = element_blank()
  )


3 Epilog

Kamu telah berhasil membuat beberapa grafik mengenai data INDO-DAPOER menggunakan ggplot2 ! Saya berharap kamu menemukan beberapa informasi menarik dari data tersebut. Berlimpahnya informasi pada data INDO-DAPOER tentunya membuat kamu tertarik untuk melakukan eksplorasi labih dalam, kan ? Pastinya akan banyak grafik-grafik berisi informasi menarik yang dapat kamu buat dengan menggunakan data tersebut.

Nah, sebagai bekal tambahan kamu, pada pembelajaran terakhir ini akan ditunjukan beberapa tips dan trik untuk mengasah kemampuan kamu membuat visualisasi dengan ggplot2. Namun, pada pembelajaran penutup ini kamu tidak akan menggunakan data INDO-DAPOER seperti sebelumnya. Lantas data apakah yang akan digunakan ?

Kamu akan menggunakan data Instagram ! Data instagram dapat diambil dengan menggunakan teknik scrapping, loh ! Apakah kamu pernah menggunakan teknik ini ?

3.1 Kon(teks)

Data yang akan digunakan adalah mengenai hashtags dalam konten Instagram. Data tersebut tersedia sebagai berkas CSV bernama hastags.csv. Kamu akan ditunjukan bagaimana cara membuat sebuah awan kata (worldcloud) dengan bantuan paket ggworldcloud berdasarkan data tersebut.

Selain itu, kamu juga akan ditunjukan bagaimana cara menggunakan fonta yang berbeda pada grafik dengan menggunakan bantuan paket showtext. Kamu akan menggunakan sebuah fonta dari Google bernama Lacquer dengan memanfaatkan fungsi font_add_google(). Ingat! Kamu* harus menjalankan showtext_auto() sebelum menjalankan baris kode pembuatan grafik agar fonta yang diimpor tersebut dapat ditampilkan dengan baik.

Begini : ****

#set library yang dibutuhkan
library("ggwordcloud")
library("showtext")
library("readr")
library("tidyverse")

#membuat variabel dataset
hashtags <- read_csv("https://storage.googleapis.com/dqlab-dataset/hashtags.csv", show_col_types = FALSE)

#melihat dataset*
glimpse(hashtags)
Rows: 60
Columns: 3
$ hashtags           <chr> "bigdata", "data", "datascience", "datascientist", …
$ count              <dbl> 489, 489, 489, 489, 489, 489, 489, 489, 489, 489, 4…
$ contains_data_word <lgl> TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, TRUE, T…
font_add_google("Lacquer")
showtext_auto()

hashtags %>%
  ggplot(
    aes(
      label = hashtags,
      size = count,
      colour = contains_data_word
    )
  ) +
  geom_text_wordcloud_area(family = "Lacquer", shape = "square") +
  scale_size_area(max_size = 20) +
  scale_colour_manual(values = c("#009AB3", "#B0E601")) +
  theme_void() +
  theme(plot.background = element_rect(fill = "#1E1E1E"))

3.2 Jumlah Rata-rata Likes per Hari

Kamu akan diajak untuk membuat sebuah grafik lolipop yang menunjukan jumlah rerata likes per hari. Data tersebut tersedia dalam berkas igstats.csv. Hal yang perlu menjadi fokus kamu pada pembelajaran ini adalah bagaimana cara memberikan anotasi teks dan panah pada grafik.

Menambahkan anotasi pada ggplot2 dapat dibilang cukup kompleks dan memerlukan ketelitian serta kesabaran tinggi. Seringkali kamu terpaksa melakukan proses trial-and-error berulang kali hingga akhirnya mendapatkan hasil yang diinginkan. Namun, semakin sering kamu melakukan proses ini maka semakin terasah pula intuisi kamu nantinya. Adapun fungsi yang akan banyak kamu pergunakan adalah annotate(). Selain itu, pada contoh berikut juga ditunjukan penggunaan format HTML (dapat juga format Markdown) pada ggplot2 menggunakan paket ggtext.

Begini :

library("ggtext")
library(forcats)
library(ggplot2)
library(dplyr)
library(readr)

igstats <- read_csv("https://storage.googleapis.com/dqlab-dataset/igstats.csv", show_col_types = FALSE)
glimpse(igstats)
Rows: 7
Columns: 5
$ day        <chr> "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Fr…
$ is_weekend <lgl> TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE
$ nposts     <dbl> 10, 103, 78, 93, 80, 108, 23
$ nlikes     <dbl> 1237, 16055, 10496, 12803, 10474, 25595, 3828
$ avglikes   <dbl> 123.7000, 155.8738, 134.5641, 137.6667, 130.9250, 236.9907,…
igstats_plot <- 
  igstats %>%
  mutate(day = fct_reorder(day, avglikes)) %>%
  ggplot() +
  geom_segment(aes(
    x = 0,
    xend = avglikes,
    y = day,
    yend = day
  ),
  colour = "white",
  linetype = "longdash"
  ) +
  geom_point(
    aes(avglikes, day, fill = is_weekend),
    shape = "circle filled",
    size = 18,
    colour = "white",
    show.legend = FALSE
  ) +
  geom_text(
    aes(avglikes, day, label = round(avglikes)),
    colour = "white",
    family = "Lacquer",
    size = 7
  ) +
  geom_text(
    aes(x = 0, day, label = day),
    colour = "white",
    nudge_y = 0.15,
    hjust = "left",
    family = "Lacquer"
  ) +
  geom_curve(
    aes(
      x = 185,
      xend = 174,
      y = 6.3,
      yend = 6
    ),
    colour = "white",
    curvature = -0.3,
    arrow = arrow(length = unit(0.1, "inches"), type = "closed")
  ) +
  geom_curve(
    aes(
      x = 185,
      xend = 230,
      y = 6.8,
      yend = 7.2
    ),
    colour = "white",
    curvature = -0.25,
    arrow = arrow(length = unit(0.1, "inches"), type = "closed")
  ) +
  annotate(
    geom = "richtext",
    x = 200,
    y = 6.5,
    label = "<span style='color:Blue'>Blue</span> is weekday,<br><span style='color:Green'>green</span> is weekend",
    fill = NA,
    label.colour = NA,
    colour = "white",
    family = "Lacquer",
    size = 4
  ) +
  annotate(
    geom = "text",
    x = 200,
    y = 3,
    label = "How many\nlikes did \nI get?",
    colour = "white",
    hjust = "center",
    family = "Lacquer",
    size = 15
  ) +
  scale_fill_manual(values = c("Blue", "Green")) +
  theme_void() +
  theme(plot.background = element_rect(fill = "Black"))

igstats_plot

3.3 Melintasi Ruang

Eits! Sebagai penutup izinkan saya mendemonstrasikan cara membuat animasi sederhana menggunakan ggplot melalui paket gganimate ya ? Tentunya kamu dipersilakan untuk menyalin kode berikut pada R-Studio yang sudah terinstall pada desktop kamu masing-masing. Kita akan menggunakan dataset igcomments.csv

Begini :

#set library yang dibutuhkan
library(showtext)
library("gganimate")
library(dplyr)
library("ggplot2")
library(hrbrthemes)

#membuat variabel dataset
komentar.ig <- read_csv("https://storage.googleapis.com/dqlab-dataset/igcomments.csv", show_col_types = FALSE)

#melihat dataset
glimpse(komentar.ig)
Rows: 495
Columns: 4
$ date       <date> 2020-08-15, 2020-08-15, 2020-08-14, 2020-08-14, 2020-08-13…
$ hour       <dbl> 19, 14, 19, 14, 14, 13, 19, 14, 19, 19, 19, 14, 19, 14, 14,…
$ is_video   <lgl> FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FAL…
$ n_comments <dbl> 3, 3, 4, 6, 0, 22, 6, 18, 0, 8, 3, 8, 5, 3, 0, 28, 2, 0, 17…
#membuat grafik
plot.komentar.ig <- komentar.ig %>%
  sample_frac() %>%
  mutate(
    frame = row_number(),
    label = format(date, format = "%e %b %y")
  ) %>%
  ggplot(aes(frame, hour, colour = is_video, size = n_comments)) +
  geom_jitter(alpha = 0.8, show.legend = FALSE) +
  scale_colour_manual(values = c("#009AB3", "#B0E601")) +
  scale_size_area(max_size = 12) +
  theme_modern_rc(
    base_family = "Roboto COndensed",
    plot_title_size = 13,
    plot_title_face = "plain",
    subtitle_size = 35,
    subtitle_face = "bold",
    caption_face = "italic"
  ) +
  theme(
    plot.title.position = "plot",
    plot.title = element_text(hjust = 0.5),
    plot.subtitle = element_text(hjust = 0.5),
    plot.caption = element_text(hjust = 0.5),
    axis.text = element_blank(),
    axis.text.x = element_blank(),
    axis.text.y = element_blank(),
    axis.title.x = element_blank(),
    axis.title.y = element_blank()
  ) +
  coord_polar()

#membuat animasi
animasi.komentar.ig <- plot.komentar.ig +
  labs(
    title = "Constellation of instagram contents!",
    subtitle = "{current_frame}",
    caption = "More comment make the star bigger\nGreen stars are video contents"
  ) +
  transition_manual(label, cumulative = TRUE) +
  enter_appear() +
  ease_aes("cubic-in-out")

#menampilkan grafik
animasi.komentar.ig
NULL