Ako želimo da vizuelizujemo podatke i pravimo lepe i kompleksne grafikone, u tome nam može pomoći paket ggplot2. To je jedan od najpopularnijih i estetski najugodnijih grafičkih okvira u R-u.

Sintaksa za izradu ggplot-a može biti zbunjujuća za početnike i one koji rade sa osnovnim graficima. Glavna razlika je u tome što, za razliku od osnovnih grafika, ggplot radi sa bazom podataka, a ne sa pojedinačnim vektorima. Svi podaci potrebni da se napravi grafik su obično sadržani unutar same baze.

Još jedna vazna odlika ggplot-a je da mozemo poboljšavati izgled dodavanjem “slojeva” (i tema) na postojeći grafik kreiran korišćenjem ggplot() funkcije.

Koristićemo bazu midwest da ilustrujemo rad sa ggplot-om. Za početak, crtamo osnovni (“prazan”) ggplot.

options(scipen=999) # iskljucujemo eksponencijalni zapis poput 1e+06
library(ggplot2)
data("midwest", package = "ggplot2")
ggplot(midwest, aes(x = area, y = poptotal)) # area i poptotal su kolone u bazi midwest

Nacrtali smo prazan ggplot. Iako su x i y navedeni, na grafiku nema tačaka niti linija. To je zbog toga što ggplot ne zna da li smo hteli scatterplot ili linijski grafik. Naveli smo ggplot-u samo koju bazu koristimo, i koje kolone želimo da budu prikazane na x i y osi. Nismo eksplicitno tražili da se nacrtaju tačke.

Primetimo da se funkcija aes() koristi da preciziramo šta se predstavlja na x, a šta na y osi. To je zbog toga što, bilo koja informacija koja je deo izvorne baze, mora biti navedena unutar aes() funkcije.

Pravljenje jednostavnog scatterplot-a

Dodajemo scatterplot na prazni ggplot dodavanjem tačaka koristeći geom “sloj” koji se naziva geom_point.

ggplot(midwest, aes(x=area, y=poptotal)) + geom_point()

Sada imamo osnovni scatterplot. Međutim, nedostaju neke važne komponente, kao što su ime grafika, oznake osa, itd. Osim toga, većina tačaka je koncentrisana u donjem delu polja, što i nije tako lepo. Videćemo kako to da ispravimo u narednim koracima.

Pored geom_point(), postoji još mnogo geom slojeva koje ćemo videti kasnije. Za sada, dodajemo još pravu koja najbolje odgovara podacima koristeći geom_smooth(method = lm). Pošto je metoda lm (skraćeno od linearnog modela), crta pravu linarne regresije.

ggplot(midwest, aes(x=area, y=poptotal)) + geom_point() + geom_smooth(method="lm") 

# mozemo staviti se = FALSE da ne crta intervale poverenja

Rekli smo da nam se ne dopada što je većina tačaka na dnu grafika, pa želimo da promenimo granice za y-osu, tako da se fokusiramo na donju polovinu.

Podesavanje granica za x i y osu

Granice se mogu podešavati na dva načina:

Metod 1: Brisanje tačaka izvan datog opsega

Ovo se može uraditi pomoću xlim() i ylim(). Prosleđujemo vektor dužine 2 (minimalnu i maksimalnu vrednost). Linije koje najbolje odgovaraju podacima (tzv. linije fitovanja) će se izmeniti u skladu sa promenama.

g = ggplot(midwest, aes(x=area, y=poptotal)) + geom_point() + geom_smooth(method="lm") 

# ostavljamo samo tacke koje se nalaze u datom opsegu
g + xlim(c(0, 0.1)) + ylim(c(0, 1000000))

U ovom slučaju, grafik nije izgrađen od nule, već je docrtan na g. To je zbog toga što je prethodni grafik sačuvan kao g, ggplot objekat, koji, kada se pozove, crta orginalni grafik. Koristeći ggplot, možemo dodavati slojeve, teme i druga podešavanja ovom grafiku.

Primećujemo da je linija fitovanja horizontalnija od one na osnovnom grafiku. To je zbog toga što, kada se koriste xlim() i ylim(), tačke van navedenog opsega se neće uzeti u obzir prilikom crtanja linije fitovanja (prave linearne regresije) (koristeći geom_smooth(method='lm')). Ovo može biti korisno kada želimo da znamo kako će izgledati linija fitovanja kada se uklone neke ekstremne vrednosti (ili autlajeri).

Metod 2: Zumiranje

Drugi metod je da promenimo granice za x i y osu tako što ćemo zumirati oblast koja nas zanima bez brisanja tačaka. Ovo radimo uz pomoć coord_cartesian().

Čuvaćemo ovaj grafik kao g1.

g = ggplot(midwest, aes(x=area, y=poptotal)) + geom_point() + geom_smooth(method="lm")  

# zumiramo bez brisanja tacaka koje su izvan granica 
# rezultujuca linija fitovanja je ista kao na prvom grafiku
g1 = g + coord_cartesian(xlim=c(0,0.1), ylim=c(0, 1000000))  # zumiramo
g1

Pošto su sve tačke uzete u obzir, linija fitovanja se nije promenila.

Promena naslova i imena osa

Sačuvali smo prethodni grafik kao g1. Hajde da dodamo naslov grafiku i nazive osama. Ovo se može uraditi odjednom koristeći funkciju labs() sa argumentima title, x i y. Druga opcija je da koristimo ggtitle(), xlab() i ylab().

g = ggplot(midwest, aes(x=area, y=poptotal)) + geom_point() + geom_smooth(method="lm") 

g1 = g + coord_cartesian(xlim=c(0,0.1), ylim=c(0, 1000000))  # zumiramo

# dodajemo naslov i imena osama
g1 + labs(title="Area Vs Population", subtitle="From midwest dataset", y="Population", x="Area", caption="Midwest Demographics")

# ili

g1 + ggtitle("Area Vs Population", subtitle="From midwest dataset") + xlab("Area") + ylab("Population")

Uradimo sve odjednom:

ggplot(midwest, aes(x=area, y=poptotal)) + 
  geom_point() + 
  geom_smooth(method="lm") + 
  coord_cartesian(xlim=c(0,0.1), ylim=c(0, 1000000)) + 
  labs(title="Area Vs Population", subtitle="From midwest dataset", y="Population", x="Area", caption="Midwest Demographics")

Promena boje i veličine tačaka

Promena boje na fiksnu vrednost

Možemo promeniti estetiku geom sloja tako sto ćemo modifikovati odgovarajuće geom-e. Promenimo boju tačaka i linije na fiksnu vrednost.

ggplot(midwest, aes(x=area, y=poptotal)) + 
  geom_point(col="steelblue", size=3) +   # podesavamo fiksnu boju i velicinu tacaka
  geom_smooth(method="lm", col="firebrick") +  # menjamo boju linije
  coord_cartesian(xlim=c(0, 0.1), ylim=c(0, 1000000)) + 
  labs(title="Area Vs Population", subtitle="From midwest dataset", y="Population", x="Area", caption="Midwest Demographics")

Promena boje po kategorijama

Ako želimo da se boja menja u odnosu na pripadnost nekoj kategoriji, odnosno na osnovu neke kolone u izvornoj bazi (midwest), to mora biti navedeno unutar aes() funkcije.

gg = ggplot(midwest, aes(x=area, y=poptotal)) + 
  geom_point(aes(col=state), size=3) +  # postavljamo da boja varira u odnosu na kategoriju state
  geom_smooth(method="lm", col="firebrick", size=2) + 
  coord_cartesian(xlim=c(0, 0.1), ylim=c(0, 1000000)) + 
  labs(title="Area Vs Population", subtitle="From midwest dataset", y="Population", x="Area", caption="Midwest Demographics")
gg

Sada se svaka tačka boji na osnovu zemlje kojoj pripada zbog aes(col = state). Ne samo boja, već i razne druge karakteristike, kao što su veličina, oblik, debljina granice, boja punjenja, itd., mogu se koristiti za razlikovanje kategorija.

Kao dodatna prednost, legenda se dodaje automatski. Ako je potrebno, može se ukloniti postavljanjem argumenta legend.position na None u theme() funkciji.

gg + theme(legend.position="None")  # brisemo legendu

Takođe, možemo u potpunosti promeniti paletu boja:

gg + scale_colour_brewer(palette = "Set1")  # menjamo paletu boja

Više ovakvih paleta se može naći u RColorBrewer paketu:

library(RColorBrewer)
head(brewer.pal.info, 10)  # prikazujemo 10 paleta
##          maxcolors category colorblind
## BrBG            11      div       TRUE
## PiYG            11      div       TRUE
## PRGn            11      div       TRUE
## PuOr            11      div       TRUE
## RdBu            11      div       TRUE
## RdGy            11      div      FALSE
## RdYlBu          11      div       TRUE
## RdYlGn          11      div      FALSE
## Spectral        11      div      FALSE
## Accent           8     qual      FALSE

Promena podeoka na osama i njihovih oznaka

Ovo ulkjučuje dva aspekta: podeoke (“breaks”) i oznake (“labels”).

Korak 1: Postavljanje prekida

Podeoci bi trebalo da budu isto skalirani kao i promenljiva x ose. Primetimo da koristimo scale_x_continuous() jer je promenljiva x ose neprekidna promenljiva. Postoje analogne funkcije za druge tipove, npr. scale_x_date(), scale_x_discrete(), itd. Naravno, postoji i ekvivalent scale_y_continuous() za y osu.

gg = ggplot(midwest, aes(x=area, y=poptotal)) + 
  geom_point(aes(col=state), size=3) +  
  geom_smooth(method="lm", col="firebrick", size=2) + 
  coord_cartesian(xlim=c(0, 0.1), ylim=c(0, 1000000)) + 
  labs(title="Area Vs Population", subtitle="From midwest dataset", y="Population", x="Area", caption="Midwest Demographics")

# menjamo podeoke na x osi
gg + scale_x_continuous(breaks=seq(0, 0.1, 0.01))

Korak 2: Promena oznaka

Po želji možemo menjati oznake podeoka na osama. Argument labels uzima vektor iste dužine kao breaks.

Demonstriraćemo ovo postavljanjem oznaka na slova od a do k (iako u ovom kontekstu to baš nema smisla):

gg = ggplot(midwest, aes(x=area, y=poptotal)) + 
  geom_point(aes(col=state), size=3) + 
  geom_smooth(method="lm", col="firebrick", size=2) + 
  coord_cartesian(xlim=c(0, 0.1), ylim=c(0, 1000000)) + 
  labs(title="Area Vs Population", subtitle="From midwest dataset", y="Population", x="Area", caption="Midwest Demographics")

# menjamo podeoke i oznake
gg + scale_x_continuous(breaks=seq(0, 0.1, 0.01), labels = letters[1:11])

Ako želimo da okrenemo skalu x ose, koristimo scale_x_reverse().

gg = ggplot(midwest, aes(x=area, y=poptotal)) + 
  geom_point(aes(col=state), size=3) +  
  geom_smooth(method="lm", col="firebrick", size=2) + 
  coord_cartesian(xlim=c(0, 0.1), ylim=c(0, 1000000)) + 
  labs(title="Area Vs Population", subtitle="From midwest dataset", y="Population", x="Area", caption="Midwest Demographics")

# okrecemo skalu na x osi
gg + scale_x_reverse()

Prilagođene oznake osa formatiranjem početnih vrednosti

Postavimo sada podeoke i na y osi. Želimo da formatiramo oznake na x i y osi. Koristimo 2 metode za formatiranje oznaka:

  • Metod 1: Korišćenje finkcije sprintf() (Menjamo prikaz oznaka na x osi u procentualni).

  • Metod 2: Korišćenje prilagođene korisnički definisane funkcije (Oznake na y osi formatiramo tako da se hiljade prikazuju kao K).

Možemo korisititi metodu koja nam odgovara.

gg = ggplot(midwest, aes(x=area, y=poptotal)) + 
  geom_point(aes(col=state), size=3) +  
  geom_smooth(method="lm", col="firebrick", size=2) + 
  coord_cartesian(xlim=c(0, 0.1), ylim=c(0, 1000000)) + 
  labs(title="Area Vs Population", subtitle="From midwest dataset", y="Population", x="Area", caption="Midwest Demographics")

gg + scale_x_continuous(breaks=seq(0, 0.1, 0.01), labels = sprintf("%1.2f%%", seq(0, 0.1, 0.01))) + 
  scale_y_continuous(breaks=seq(0, 1000000, 200000), labels = function(x){paste0(x/1000, 'K')})

Prilagođavanje cele teme odjednom koršišćenjem ugrađenih tema

Umesto da pojedinačno menjamo komponente teme, možemo da promenimo celu temu koristeći unapred izgrađene teme.

Ovo opet može da se radi na nekoliko načina.

Možemo koristiti theme_set() da postavimo temu pre crtanja ggplot-a. Moramo imati na umu da ce ovo podešavanje uticati na sve buduće grafike. Crtamo ggplot,a zatim dodajemo ukupnu postavku teme (npr. theme_bw()):

gg = ggplot(midwest, aes(x=area, y=poptotal)) + 
  geom_point(aes(col=state), size=3) +  
  geom_smooth(method="lm", col="firebrick", size=2) + 
  coord_cartesian(xlim=c(0, 0.1), ylim=c(0, 1000000)) + 
  labs(title="Area Vs Population", subtitle="From midwest dataset", y="Population", x="Area", caption="Midwest Demographics")

gg = gg + scale_x_continuous(breaks=seq(0, 0.1, 0.01))

# Metod 1: Koristeci theme_set()
theme_set(theme_classic()) 
gg

# Metod 2: Dodavanje slojeva tema
gg + theme_bw() + labs(subtitle="BW Theme")

gg + theme_classic() + labs(subtitle="Classic Theme")

Više interesantnih tema možemo potražiti u paketima ggthemes i ggthemer.

To bi bilo to za početak. Sada smo sposobni da se pozabavimo naprednijim prilagođavanjem - razmotrićemo modifikovanje komponenata teme, manipulaciju legendama, komentarima, prilagođavanje izgleda, itd.