Kodas
install.packages("ggplot2")ggplot2
Bene populiariausia bazinio R grafikos alternatyva – paketas ggplot2, paremtas „grafikų gramatikos“ principu (Wilkinson 2005). Grafikos gramatikos esmė – iš nepriklausomų komponentų (sluoksnių) sudaryti vientisą vizualizaciją.
Šioje konspekto dalyje pateiksime tik trumpą ggplot2 paketo įžangą ir apžvalgą. Apie paketo funkcijas, naudojimą ir kitas subtilybes galima perskaityti paketo autoriaus Hadley Wickham knygoje (nuoroda).
ggplot2 paketo naudojimas R ir duomenų analitikos pradžiamoksliams vertinamas nevienareikšmiškai. Pavyzdžiui, šis Jeff Leek apmąstymas (nuoroda). Su tuo būtų galima sutikti, kadangi mokant bazinio R subtilybes, galima braižyti lygiai tokius pat vizualiai tvarkingus, estetiškus grafikus kaip ir su ggplot2 (pvz. Karolio Koncevičiaus blogas, arba šis blogas).
Šiuolaikinę grafikų gramatika buvo sukurta tam, kad aprašytų pagrindinius bendrus principus grafikų sudaryme. Trumpai, tai grafikas sieja duomenis su geometrinių objektų (taškų, linijų, stulpelių) estetinėmis savybėmis (spalva, forma, dydžiu ir kt.). Be to, grafike gali būti taikomos statistinės transformacijos, apibrėžiama koordinačių sistema. Būtent šių nepriklausomų komponentų kombinacija ir sudaro grafiką.
Toliau trumpai apibrėšime komponentus ir terminus, kuriais remsimės vėliau. Visi grafikai su daromi iš duomenų, atvaizduojamos informacijos, ir iš pačio atvaizdavimo (angl. mapping), aprašymo, kaip duomenys yra atvaizduojami į estetines savybes. Yra penki pagrindiniai atvaizdavimo komponentai:
sluoksnis (layer) - geometrijų (geoms) ir statistinių transformacijų (stats) rinkinys. Geometrijos – tai matomi elementai (taškai, linijos, poligonai ir pan.), o transformacijos apibendrina duomenis (pvz., sugrupuoja ir suskaičiuoja stebinius histogramai arba pritaiko tiesinį
skalės (scale) - susieja duomenų reikšmes su estetinių požymių reikšmėmis (spalva, forma, dydis). Skalės taip pat braižo ašis ir legendas;
koordinatės (coord) - apibrėžia, kaip duomenų koordinatės atvaizduojamos plokštumoje. Įprastai naudojamos Dekarto koordinatės, bet galima rinktis ir kitas sistemas (pvz., poliarines ar žemėlapių projekcijas);
aspektas (facet) - nurodo, kaip suskaidyti duomenis į grupes ir kiekvienai iš jų nubraižyti atskirą grafiką;
tema (theme) - smulkūs pateikimo parametrai: šriftai, fonas, kraštinės ir pan.
Pirmiausia instaliuojame ir išsikviečiame ggplot2 paketą.
install.packages("ggplot2")Kartu su paketu įrašomas ir duomenų rinkinys mpg. Jame pateikiami duomenys apie JAV populiarių 1999-2008 m. automobilių modelių kuro suvartojimą.
| manufacturer | model | displ | year | cyl | trans | drv | cty | hwy | fl | class |
|---|---|---|---|---|---|---|---|---|---|---|
| audi | a4 | 1.8 | 1999 | 4 | auto(l5) | f | 18 | 29 | p | compact |
| audi | a4 | 1.8 | 1999 | 4 | manual(m5) | f | 21 | 29 | p | compact |
| audi | a4 | 2.0 | 2008 | 4 | manual(m6) | f | 20 | 31 | p | compact |
| audi | a4 | 2.0 | 2008 | 4 | auto(av) | f | 21 | 30 | p | compact |
| audi | a4 | 2.8 | 1999 | 6 | auto(l5) | f | 16 | 26 | p | compact |
| audi | a4 | 2.8 | 1999 | 6 | manual(m5) | f | 18 | 26 | p | compact |
Toliau iliustruojant pavyzdžius remsimės mpg duomenų rinkiniu.
Pradinis bet kokio grafiko elementas yra duomenys. Geriausiai ggplot2 veikia su tvarkingo (angl. tidy) formato duomenimis, kur lentelės struktūros duomenyse eilutės atitinka stebėjimus, o stulpeliai - kintamuosius.
Duomenys perduodami funkcijai ggplot() tam, kad kitos grafiko braižymo dalys žinotų iš kur paimti kintamuosius.
ggplot(data = mpg)
Kol kas nieko nematome grafike, kadangi nenurodyta nei kas bus atvaizduojama, nei kokios komponentės sudarys grafiką.
Atvaizdavimas paprasčiausiai yra instrukcijų rinkinys kaip duomenys turi būti susieti su geometriniais objektais. Tai atliekama naudojant aes() funkciją, kurios rezultatas yra priskiriamas ggplot() funkcijos argumentui mapping.
Pavyzdžiui, norime atvaizduoti kuro suvartojimo greitkelyje (hwy) ir variklio darbinio tūrio litrais (displ) ryšį. Šie kintamieji atitinkamai nurodys taškų x ir y koordinates.
Dabar grafike galime matyti koordinačių ašių skales ir ašių pavadinimus bei sudarytą gardelę.
Sluoksniai yra esminės grafiko sudedamosios dalys. Kiekvienas sluoksnis sudarytas iš trijų esminių dalių:
geometrija nurodo kokiu būdu duomenys yra atvaizduojami, ar tai taškai, tiesės, stačiakampiai;
statistinės transformacijos gali suskaičiuoti ar sudaryti naujus kintamuosius iš duomenų ir turi įtakos tam, kas atvaizduojama;
pozicijos koregavimas nustato kurioje grafiko vietoje duomenys turi būti atvaizduojami.
Sluoksnių sudarymui naudojamos geom_*() ir stat_*() funkcijos, kur vietoje * nurodomas geometrinis objektas, pvz. taškas geom_point().
Pavyzdžiui, prie turimo grafiko pridėsime (tiesiogine prasme) taškus, kuriuos atitinka koordinačių poros (hwy, displ).
ggplot(data = mpg, mapping = aes(x = hwy, y = displ)) +
geom_point()
Funkcijų ggplot() ir aes() pirmieji du argumentai visada yra tokie patys, tai paskutinę komandą galima užrašyti trumpiau.
ggplot(mpg, aes(hwy, displ)) +
geom_point()Pridėti papildomus kintamuosius į grafiką galima pasitelkiant kitas estetikas, tokias kaip spalva, forma ir dydis. Jos veikia taip pat, kaip x ir y estetikos, ir nurodomos funkcijos aes() viduje:
Naudojant skalę ggplot2 pasirūpina kintamųjų reikšmių susiejimu su estetika (pvz. su spalvomis raudona, geltona, žalia). Kiekvienai estetikai (spalva, forma, dydis) taikoma atskira skalė. Ji ne tik atlieka šį susiejimą, bet ir automatiškai sukuria gaires (legendą ar ašį), kad grafiką būtų lengva skaityti. Skalės taip pat atsakingos už koordinačių ašių reikšmių ribas, žymių formatavimus.
Pavyzdžiui, įtrauksime dar vieną estetinę geometrinių objektų savybę - taškų spalvą, kurios skalė bus nusakoma kintamojo class reikšmėmis.
ggplot(mpg, aes(displ, hwy, colour = class)) +
geom_point()
Matome, kad taškai sugrupuoti į spalvas, kur skirtingą spalvą atitinką viena iš kintamajo class reikšmių. Grafiko dešinėje pusėje automatiškai sudaroma spalvų skalės legenda.
Jeigu norėtume, kad visi taškai būtų nuspalvinti viena fiksuota spalva, tai galime padaryti ne aes() funkcijoje, o individualiame sluoksnyje.
ggplot(mpg, aes(displ, hwy)) +
geom_point(colour = "purple")
Šiuo metu esame parinkę estetiką ir jai priskirtą skalę, tačiau pačios skalės dar nevaldome. Skales valdančios funkcijos turi šabloną scale_{aesthetic}_{type}, kur:
{aesthetic} yra viena iš parinktų estetikų funkcijoje aes() (pvz. colour, shape, size, x, y),
{type} - konkreti skalės rūšis (pvz. continuous, discrete, manual, log10, gradient ir kt.).
Pavyzdžiui, pakeisime spalvos estetikos skalę į vieną iš tipų viridis_d.
ggplot(mpg, aes(hwy, displ, colour = class)) +
geom_point() +
scale_colour_viridis_d()
Taip pat galime su skalėmis koreguoti ir ašis, nes jos taip pat yra estetinis atributas. Šiuo atveju mūsų abscisių ašis \(x\) yra tolydi, todėl naudojant funkciją scale_x_continuous() perkelsime ašį į grafiko viršų, nustatysime ašies pavadinimą ir jos ribas.
ggplot(mpg, aes(cty, hwy, colour = class)) +
geom_point() +
scale_colour_viridis_d() +
scale_x_continuous(
position = "top",
name = "kuro sąnaudos greitkelyje",
limits = c(5, 45)
)
Kartais norime atvaizduoti tik tam tikrą dalį viso grafiko, kitaip tariant priartinti grafiko dalį. Natūralu, kad tokiu atveju reikėtų sumažinti ašių ribas iki norimo intervalo. Pavyzdžiui pateiktame grafike nustatysime \(y\) ašies ribas nuo 10 iki 35 trim būdais ir taip pat pateiksime originalų grafiką be ašių ribų koregavimo.
# originalios y ašies ribos
pagrindinis <- ggplot(mpg, aes(drv, hwy)) +
geom_hline(yintercept = 28, colour = "red") +
geom_boxplot() +
labs(title = "originalas")
# koreguota per coord_cartesian() funkciją
p_coord_cart <- pagrindinis + coord_cartesian(ylim = c(10, 35)) + labs(title = "coord_cartesian()")
# koreguota per skalės funkciją
p_skale <- pagrindinis + scale_y_continuous(limits = c(10, 35)) + labs(title = "scale_y_continuous()")
# koreguota per ylim() funkciją
p_ylim <- pagrindinis + ylim(10, 35) + labs(title = "ylim()")
gridExtra::grid.arrange(pagrindinis, p_coord_cart, p_skale, p_ylim, ncol = 2)
Originaliame grafike antros stačiakampės diagramos mediana yra 28, būtent ties šia reikšmė nubrėžta raudona horizontali \(y = 28\) tiesė.
Akivaizdu, kad keičiant ašies ribas su funkcijomi scale_y_continuous() ir ylim() iškraipomas stačiakampių diagramų vaizdas ir reikšmių pasiskirstymas. Tai nutinka todėl, kad šios funkcijos visas reikšmes nesančias intervale \([10, 35]\) konvertuoja į NA prieš skaičiuojant statistikas. Šiuo atveju prieš braižant stačiakampes diagramas, kurioms reikia įvertintų kvartilių.
Tik naudojant funkciją coord_cartesian() galima tinkamai priartinti grafiko dalį nepakeičiant grafike vaizduojamų objektų išdėstymo ar reikšmių pasiskirstymo.
Aspektai - tai būdas tą pačią grafiko struktūrą pavaizduoti atskiriems duomenų pogrupiams. Aspektavimas suskaido duomenis pagal vieną ar kelis kintamuosius ir kiekvienam pogrupiui nubraižo tą patį grafiką, taip sukuriant tarsi grafikų „lentelę“.
Skiriami du pagrindiniai tipai: wrapped (suvyniotas) ir grid (tinklelis). Dažniausiai praktiškiausias yra suvyniotas, todėl pirmiausia verta susipažinti būtent su juo.
Nubrėšime pradinio hwy ir displ kintamųjų taškų sklaidos diagramos grafiką, tik šį kartą naudosime class kintamąjį ne taškų spalvai nusakyti, o išskaidyti grafiką į duomenų grupių grafikus. Suvyniotam aspektavimui naudojama funkcija facet_wrap(), kurioje kaip formulę nurodome pagal kokį kintamąją atliekamas skaidymas (~kintamasis).
ggplot(mpg, aes(hwy, displ)) +
geom_point() +
facet_wrap(~class)
Gavome tų pačių kintamųjų dvimačių taškų sklaidos diagramą kiekvienai iš class grupių.
Grafikų išdėstymą galima kontroliuoti su argumentais nrow ir ncol. Pavyzdžiui nustatysime, kad iš viso būtų 4 eilutės.
ggplot(mpg, aes(hwy, displ)) +
geom_point() +
facet_wrap(~class, nrow = 4)
Kai nurodomi abu parametrai ncol ir nrow, pirmumo teisė suteikiama parametrui ncol.
ggplot(mpg, aes(hwy, displ)) +
geom_point() +
facet_wrap(~class, nrow = 4, ncol = 5)
Jeigu norime skaidymą daryti pagal du kategorinius kintamuosius, pravartu naudoti tinklelio išskaidymą su funkcija facet_grid(). Šįkart užrašant skaidymą kaip formulę, kairėje pusėje nurodomas kintamasis atitinka grupes y ašyje, o kintamasis dešinėje formulės pusėje - x ašies grupes (y ~ x).
ggplot(mpg, aes(hwy, displ)) +
geom_point() +
facet_grid(class ~ year)
Tema iš esmės leidžia kontroliuoti visas grafiko vizualines dalis, kurios nėra susijusios su duomenimis. Pavyzdžiui, legendos vieta, fono spalva, šriftas, ašis ir ašių linijas, panelių juostas ir t.t.
Skirtingai nei geomai (geoms) ir skalės (scales), temos nekeičia duomenų atvaizdavimo ar transformacijų – jos skirtos stiliui suvienodinti, priderinti prie dizaino gairių ir padaryti grafiką estetišką. Praktikoje išvaizdą koreguojama naudodami paruoštas theme_*() funkcijas (pvz. theme_minimal(), theme_classic()) ir, jei reikia, smulkiai detalizuojama theme() su element_*() komponentais (pvz., element_text(), element_line(), element_rect()).
Toks aiškus duomenų ir ne duomenų dalių atskyrimas skiriasi nuo base ir lattice grafikų, kur funkcijos vienu metu turi daug argumentų abiem sritims, todėl sudėtinga tokias funkcijas išmokti valdyti. Su ggplot2 pirmiausia nusprendžiama, kaip rodomi duomenys, o po to temos leidžia redaguoti pateikimo detales.
Pavyzdžiui, pritaikysime kelias jau egzistuojančias, paruoštas temas. Pagal nutylėjimą standartinio ggplot2 grafiko tema yra theme_grey().
df <- data.frame(x = 1:3, y = 1:3)
p <- ggplot(df, aes(x, y)) + geom_point()
gridExtra::grid.arrange(
p + theme_grey() + ggtitle("theme_grey()"),
p + theme_bw() + ggtitle("theme_bw()"),
p + theme_linedraw() + ggtitle("theme_linedraw()"),
ncol = 3
)
gridExtra::grid.arrange(
p + theme_light() + ggtitle("theme_light()"),
p + theme_dark() + ggtitle("theme_dark()"),
p + theme_minimal() + ggtitle("theme_minimal()"),
ncol = 3
) 
Čia pateiktos kartu su ggplot2 paketu atėjusios temos. Tačiau yra kitų paketų, pvz. ggthemes, kuriuose yra dar daugiau galimų temų variantų.
library(ggthemes)
gridExtra::grid.arrange(
p + theme_solarized() + ggtitle("theme_solarized()"),
p + theme_map() + ggtitle("theme_map()"),
p + theme_excel() + ggtitle("theme_excel()"),
ncol = 3
)
Galima pasirinkus egzistuojančia temą koreguoti jos tam tikrus elementus su funkcija theme(). Dažniausiai naudojama tokia struktūra grafikas + theme(element.name = element_function()). Pavyzdžiui, grafiko pavadinimo elementui, kuris iš esmės yra tekstas, galima naudoti element_text() funkciją. Ši funkcija leidžia keisti teksto dydį, spalvą, šriftą, padėtį.
p_pavadintas <- p + labs(title = "Čia grafikas su ggplot")
p_pavadintas +
theme(plot.title = element_text(size = 16, face = "italic", colour = "purple3", hjust = 1))