ggplot2
Pakett ggplot2
:
qplot()
ehk quick plot,
mis on paketi vaste R-i baasgraafika funktsioonile plot()
.
Põhjalikumalt ja paindlikumalt on võimalik graafikuid kujundada
funktsiooniga ggplot()
.# Esimesel korral tuleb pakett installida
# install.packages("ggplot2")
# Paketi kasutamiseks laadi pakett
library(ggplot2)
Ggploti spikri leiad siit, levinumad funktsioonid siit.
Kasutame sel korral 2023. aasta riigikogu valimiste andmeid, mis on kraabitud lehelt https://rk2023.valimised.ee/et/detailed-voting-result/index.html. Lisaks oleme tabelisse lisanud kandidaatide vanuse, soo ja tähtkuju.
Enne, kui hakkame ise ggploti graafikuid nullist ehitama, vaatame üht
RStudio lisandmoodulit (addin) nimega esquisse
,
mis võimaldab andmestikke ggplotiga visualiseerida interaktiivse
kasutajaliidese abil, ilma koodi ise kirjutamata.
Lisandmooduliga saab
# installime paketi
install.packages("esquisse")
# kasutame paketist 'esquisse' funktsiooni 'esquisser()'
esquisse::esquisser()
# sama saaksime teha ka tavaliselt paketti laadides ja seejärel funktsiooni kasutades
library(esquisse)
esquisser()
Mõtleme andmestikus olevate tunnuste tüüpidele ning püüame lisandmooduliga visualiseerida
Kõige esimeseks kihiks loob funktsioon ggplot()
tühja
kihi, kus saab täpsustada mida ja millise
graafiku osana kuvada. Seda, mis tabelist andmed võetakse,
tuleb täpsustada argumendiga data
.
Andmestiku tunnuste visualiseerimiseks kasutatakse
argumenti mapping
ja selle väärtusena funktsiooni
aes
(aesthetics). aes
’i argumentidega
(sulgude sees) on omakorda võimalik öelda näiteks, et visualiseeri
mingit andmestiku tunnust graafikul
x = ...
),y = ...
),color = ...
),fill = ...
),shape = ...
),size = ...
),alpha = ...
),linetype = ...
)Üht ja sama tunnust võib visualiseerida ka mitme aes
’i
argumendiga (nt võime kandidaatide sugu väljendada ühel ja samal
joonisel nii eraldi tulpadena x-teljel kui ka erineva tulba
täitevärviga).
Kui tahame valimiste andmestikust visualiseerida x-teljel soo
kategooriaid, siis täpsustame selle argumendiga
mapping = aes(x = sugu)
. Kui andmestik on täpsustatud, siis
aes
-funktsiooni sees pole vaja tulbale enam dollarimärgiga
viidata, piisab lihtsalt tulba nimest.
Kuna me ei ole veel öelnud, mismoodi me sugu tahame graafikul kuvada (nt kas tulpdiagrammina või pirukana, ehkki päris piruka funktsiooni ggplotis ei olegi), siis joonistatakse endiselt tühi palett, mille x-teljele on nüüd märgitud soo kategooriad.
Nii data
’t kui ka mapping
’ut on võimalik
täpsustada ka hilisemates kihtides, kusjuures argumentide nimed
(data =
ja mapping =
) võib ka ära jätta, kui
nende järjekord on õige.
Laadi RStudiosse eelmistes praktikumides
kasutatud küsimustik. Loo ggplot
’i kiht, kus x-teljel oleks
sünniaasta ja y-teljel oleks õpitud aastate arv.
Teine kiht täpsustab, millist graafiku tüüpi mingi
tunnuse või tunnuste kuvamiseks kasutada. Seda kihti nimetatakse
geom_function
’iks. Levinumad geom’id
on
geom_point()
(hajuvusdiagrammid),geom_count()
(hajuvusdiagrammid, kus kattuvad punktid
on suuremad),geom_histogram()
(histogrammid),geom_boxplot()
(karpdiagrammid),geom_bar()
(tulpdiagrammid, kui sagedused tuleb
arvutada),geom_col()
(tulpdiagrammid, kui sagedused on juba
arvutatud),geom_label()
(sildid),geom_text()
(tekst),geom_line()
(joondiagrammid),geom_smooth()
(trendijooned),# Jätame ära argumentide nimed "data" ja "mapping"
ggplot(valimised,
aes(x = sugu)) +
geom_bar()
# Käsku võib lugeda nii:
# kasuta andmestikust 'valimised'
# graafiku x-teljel kuvamiseks
# tunnust 'sugu' nii,
# et graafiku tüübiks on tulpdiagramm.
geom_bar()
on funktsioon, mis loeb
kategoriaalse tunnuse tasemed vaikimisi kokku ja paneb y-teljele
tasemete sagedused, ilma et peaksime sageduste leidmiseks esmalt nt
table()
-funktsiooni kasutama ja seda
data.frame
’iks teisendama.
Kui andmestikus oleks juba eraldi tulp sagedustega,
peaksime aes()
-funktsioonis täpsustama selle tulba
y-argumendi väärtusena (y = sageduste_tulp
) ning kasutama
geom_bar()
funktsiooni sees argumenti
stat = "identity"
või kasutama geom_bar()
asemel funktsiooni geom_col()
.
ggplot(data.frame(table(valimised$sugu)),
aes(x = Var1, y = Freq)) + # y-teljel sagedused
geom_bar(stat = "identity")
# või
ggplot(data.frame(table(valimised$sugu)),
aes(x = Var1, y = Freq)) +
geom_col()
Sellisest sagedustega andmestikust saab teha ka piruka ehk sektordiagrammi.
ggplot(data.frame(table(valimised$sugu)),
aes(x = "", y = Freq, fill = Var1)) +
geom_col() +
coord_polar(theta = "y")
Sektordiagrammide jaoks on aga parem ggploti täiendav pakett ggtricks
.
Nagu öeldud, võib data
’t ja tunnuste
mapping
’ut täpsustada ka geom
-kihtides.
Näiteks ülal oleva graafiku saame ka sellise koodiga:
Selline vormistus on kasulik eriti siis, kui tahame kujutada samal
graafikul erinevate andmestike või sama andmestiku erinevate alamhulkade
tunnuseid (iga kujutusviisi jaoks tuleb teha eraldi
geom
-kiht). Näiteks võime samal graafikul kujutada lisaks
eraldi joonega ainult mingi valimisnimekirja, nt
sotsiaaldemokraatide mees- ja naiskandidaatide arvu.
geom_line
on nn kollektiivne geom
ehk selle joonistamiseks kasutatakse mitme vaatluse andmeid (joont ei
saa joonistada ainult 1 vaatluse põhjal). Selleks, et joon oleks
tõmmatud üle kõikide kategooriate (siin mees- ja naiskandidaatide
tulpade), kasutame aes
-funktsiooni sees argumenti
group
.
Kui joone tõmbamiseks vajalikke vaatlusi ei grupeeri mingi andmestiku
tunnus, võib group
’i väärtus olla mis tahes konstant, nt 1,
500, “a”, “konstant” vmt.
# stat = "count" tuleb lisada, et
# ggplot teaks, kust tulevad joone jaoks y-teljele sagedused
# ("count" ehk "loe kokku").
ggplot() +
geom_bar(data = valimised,
aes(x = sugu)) +
geom_line(data = valimised[valimised$nimekiri == "Sotsiaaldemokraatlik Erakond",],
aes(x = sugu, group = 1), # vaatame küll ainult sotside nimekirja kandidaate, aga neid omakorda edasi ei grupeeri ükski andmestiku tunnus (group = konstant)
stat = "count",
color = "tomato1")
Kui aga tahta grupeerida vaatlusi mingi andmestiku tunnuse järgi (nt
valimisnimekiri) ning näidata seega kõiki selle tunnuse
alusel tekkivaid andmestiku alamosi korraga, tuleb group
väärtuseks panna seesama andmestiku tunnus ise. Sel juhul ei tule iga
tunnuse taseme kohta tekitada uut geom
-kihti omaette
alamandmestikuga (nt
valimised[valimised$nimekiri == "Sotsiaaldemokraatlik Erakond",]
,
valimised[valimised$nimekiri == "Eesti Reformierakond",]
jne). Kuvame näiteks kõikide erakondade mees- ja naiskandidaatide arvu
üldiste tulpade peal eri värvi joontena.
ggplot() +
geom_bar(data = valimised,
aes(x = sugu)) +
geom_line(data = valimised,
aes(x = sugu,
group = nimekiri, # grupeeriv tunnus
color = nimekiri), # värvime ka jooned grupeeriva tunnuse järgi (värv nüüd aes()-funktsiooni sees!)
stat = "count")
# Need data ja aes osad, mis kahel geom-kihil kattuvad
# (data = valimised ja aes(x = sugu)),
# võib liigutada ka lihtsalt ggplot()-funktsiooni sisse
ggplot(valimised, aes(x = sugu)) +
geom_bar() +
geom_line(aes(group = nimekiri,
color = nimekiri),
stat = "count")
Võrdle:
ggplot(valimised, aes(x = sugu)) +
geom_bar() +
geom_line(aes(group = 1), # grupeeriv konstant
color = "red", # joone värv ei sõltu mingist andmestiku tunnusest
stat = "count")
Laadi RStudiosse eelmistes
praktikumides kasutatud küsimustik. Loo ggplot
’i kiht, kus
x-teljel oleks sünniaasta ja y-teljel oleks õpitud aastate
arv.
Kuva sünniaasta ja õpitud aastate arvu suhet
hajuvusdiagrammil.
Kolmas kiht lubab modifitseerida seda, kuidas mingil
kujul graafikul esitamiseks valitud tunnus graafikul täpselt välja näeb.
Seda kihti nimetatakse scale_function
’iks.
scale
’iga saab modifitseerida konkreetselt seda
elementi, mille kaudu tunnust graafikul kujutatud on, nt
scale_x_...
, scale_y_...
,
scale_color_...
, scale_fill_...
,
scale_size_...
, scale_shape_...
,
scale_alpha_...
, scale_linetype_...
jne.
scale
-funktsiooni nime viimane element (üleval märgitud
praegu punktiiriga) kirjeldab tunnuse modifitseerimise tüüpi,
värviskaalat vms. See, mis argumendid mingil konkreetsel
scale
-funktsioonil on, sõltub funktsioonist endast. Trüki
konsooli nt scale_
ja vajuta tabulaatorit, et näha
erinevaid variante.
Kasutame siin scale
-funktsiooni, et nimetada soo
tasemeid graafiku x-teljel pikemalt (vastavalt sõnadega
mehi ja naisi) ja kasutada valimisnimekirja joontena
kuvamiseks ggploti vaikimisi pakutud värvide asemel
enda määratud värve. Värvivektoris võib värve määrata kas värvinimede
kaudu (nt c("red", "blue")
, vt ka colors()
),
hex-värvikoodide kaudu (nt c("#FF0000", "#0000FF")
) või
määrates eraldi punase, rohelise ja sinise tooni suhte funktsioonis
rgb()
(nt
rgb(red = 0, blue = 255, green = 0, maxColorValue = 255)
).
ggplot(valimised, aes(x = sugu)) +
geom_bar() +
geom_line(aes(group = nimekiri, color = nimekiri), stat = "count") +
scale_x_discrete(labels = c("mehi", "naisi")) +
scale_color_manual(values = c("#007154", "#0073B7", "#F7DB00", "#858C92", "#2E2990", "#91C33C", "#F75E00", "#0594DA", "#DA0600", "#000000"))
# 'labels'-argument nimetab joonisel soo tasemed ümber (aga mitte andmestikus!)
# 'scale_color_manual' laseb määrata tunnuse tasemetele käsitsi uued värvid
color
täpsustab ggplotis joonte (nt joongraafiku või
tulpade jm-de kujundite piirjoonte) värvi. Täitevärvi jaoks on ggplotis
aes
-funktsiooni argument nimega fill
. Kujutame
nüüd tulpdiagrammi x-teljel hoopis nimekirja ja sugu tulpade
täitevärvina (fill
). Tahtes määrata vaikimisi täitevärvide
asemel muid värve, tuleb sellisel juhul täpsustada seda kihil, mis algab
tekstiga scale_fill_...
. Võime määrata värvid taas kord
käsitsi, kui kasutame funktsiooni
scale_fill_manual(values = c("värv1", "värv2"))
või
kasutada juba mõnd olemasolevat värvipaletti, nt ColorBreweri
omade hulgast.
ggplot(valimised, aes(x = nimekiri, fill = sugu)) +
geom_bar() +
scale_fill_brewer(type = "qual", # kvalitatiivne tunnus
palette = 2, # 2. värvipalett
direction = -1) # keera palett vastupidi
Vaikimisi sätitakse soo kategooriad üksteise otsa
(position = "stack"
). Võime aga geom_bar()
funktsiooni sees täpsustada, et
geom_bar(position = "dodge")
) või etgeom_bar(position = "fill")
).ggplot(valimised, aes(x = nimekiri, fill = sugu)) +
geom_bar(position = "dodge") + # meeste ja naiste tulbad kõrvuti
scale_fill_brewer(type = "qual", palette = 2, direction = -1)
ggplot(valimised, aes(x = nimekiri, fill = sugu)) +
geom_bar(position = "fill") + # meeste ja naiste osakaalud
scale_fill_brewer(type = "qual", palette = 2, direction = -1)
Kuna x-telje sildid kipuvad praegu üksteise peale jooksma, on üks variant keerata kogu joonis 90 kraadi paremale nii, et nimekirjade sildid jääksid x-telje asemel y-teljele.
ggplot(valimised, aes(y = nimekiri, fill = sugu)) +
geom_bar(position = "dodge") +
scale_fill_brewer(type = "qual", palette = 2, direction = -1)
# või
ggplot(valimised, aes(x = nimekiri, fill = sugu)) +
geom_bar(position = "dodge") +
scale_fill_brewer(type = "qual", palette = 2, direction = -1) +
coord_flip() # võib lisada ka funktsiooni, mis vahetab x- ja y-telje ära
Üks asi, mida kindlasti tulpdiagrammidega sageli vaja läheb, on
tulpade ümberjärjestamine. Üks võrdlemisi kohmakas, aga
lihtne ja läbipaistev viis seda teha on anda kategooriate järjekord
tekstivektorina ette selle telje scale
-kihil, kus
järjestatavate kategooriate nimed on (meie näites
scale_y_...
). Näiteks kui tahame kuvada tulpasid selle
põhjal, kui palju üldse nimekirjades kandidaate kokku on, saame leida
selle esmalt table()
-funktsiooniga, sorteerida
sagedustabeli ja küsida sorteeritud tabeli kategooriate nimesid.
t.nimekiri <- table(valimised$nimekiri)
kandidaate_kokku <- names(sort(t.nimekiri))
ggplot(valimised, aes(y = nimekiri, fill = sugu)) +
geom_bar(position = "dodge") +
scale_fill_brewer(type = "qual", palette = 2, direction = -1) +
scale_y_discrete(limits = kandidaate_kokku) # limits argumendi väärtuseks on kategooriate puhul nende järjestatud vektor
Kui tahame sorteerida selle järgi, kui palju (absoluutarvuna) nimekirjas on naisi, peame tegema sama asja soo ja nimekirja risttabeli naiste reaga.
t.sugu.nimekiri <- table(valimised$sugu, valimised$nimekiri)
naiskandidaate <- names(sort(t.sugu.nimekiri["N",]))
ggplot(valimised, aes(y = nimekiri, fill = sugu)) +
geom_bar(position = "dodge") +
scale_fill_brewer(type = "qual", palette = 2, direction = -1) +
scale_y_discrete(limits = naiskandidaate)
Veelgi ausam oleks sorteerida selle põhjal, kui suur on nimekirjas naiskandidaatide osakaal.
t.sugu.nimekiri.props <- prop.table(t.sugu.nimekiri, margin = 2)
naiskandidaatide_osakaal <- names(sort(t.sugu.nimekiri.props["N",]))
ggplot(valimised, aes(y = nimekiri, fill = sugu)) +
geom_bar(position = "dodge") +
scale_fill_brewer(type = "qual", palette = 2, direction = -1) +
scale_y_discrete(limits = naiskandidaatide_osakaal)
Teiste meetoditega kategooriate sorteerimisest võib lugeda rohkem näiteks siit või siit.
Laadi RStudiosse eelmistes
praktikumides kasutatud küsimustik. Loo ggplot
’i kiht, kus
x-teljel oleks sünniaasta ja y-teljel oleks õpitud aastate arv.
Kuva sünniaasta ja õpitud aastate arvu suhet
hajuvusdiagrammil.
Tähista erineva värviga need vastajad,
kellel on kvantitatiivsete meetoditega kogemust, ja need, kellel ei ole.
Kasuta kategooriate jaoks värve “grey45” ja “orange”.
Neljandal kihil võime täpsustada telgede ja graafikute pealkirjad,
alapealkirjad jmt funktsiooniga labs()
.
ggplot(valimised, aes(y = nimekiri, fill = sugu)) +
geom_bar(position = "dodge") +
scale_fill_brewer(type = "qual", palette = 2, direction = -1) +
scale_y_discrete(limits = naiskandidaatide_osakaal) +
labs(x = "Kandidaatide arv",
y = "",
fill = "Sugu",
title = "Mees- ja naiskandidaatide arv",
subtitle = "Riigikogu valimistel 2023",
caption = "Andmed: https://rk2023.valimised.ee/et/candidates")
ggplot
’i graafikuid saab ka salvestada eraldi
objektidesse, et neid taaskasutada. Salvestame meie praeguse joonise
objekti nimega p.
p <- ggplot(valimised, aes(y = nimekiri, fill = sugu)) +
geom_bar(position = "dodge") +
scale_fill_brewer(type = "qual", palette = 2, direction = -1) +
scale_y_discrete(limits = naiskandidaatide_osakaal) +
labs(x = "Kandidaatide arv",
y = "",
fill = "Sugu",
title = "Mees- ja naiskandidaatide arv",
subtitle = "Riigikogu valimistel 2023",
caption = "Andmed: https://rk2023.valimised.ee/et/candidates")
Laadi RStudiosse eelmistes
praktikumides kasutatud küsimustik. Loo ggplot
’i kiht, kus
x-teljel oleks sünniaasta ja y-teljel oleks õpitud aastate arv.
Kuva sünniaasta ja õpitud aastate arvu suhet hajuvusdiagrammil.
Tähista erineva värviga need vastajad, kellel on kvantitatiivsete
meetoditega kogemust, ja need, kellel ei ole. Kasuta kategooriate jaoks
värve “grey45” ja “orange”.
Lisa graafikule pealkiri “Õpitud aastate
seos sünniaastaga”, alapealkiri “ja kokkupuutega kvantitatiivsete
meetoditega” ning legendi pealkiri “Kogemused kvantitatiivsete
meetoditega”.
Viiendal kihil võime täpsustada otseselt andmetega mitteseotud
elementide väljanägemist graafikul funktsiooniga theme()
.
Selliste elementide hulka kuuluvad näiteks üldine teksti suurus, värv,
font, paksus, paiknemine, graafiku tausta värv, graafiku piirjoonte
olemasolu, paksus, värv, taustaruudustiku kuvamine, legendi asukoht jne.
On terve hulk n-ö sisse-ehitatud teemasid, nt theme_bw()
,
theme_grey()
, theme_light()
,
theme_dark()
, theme_minimal()
,
theme_classic()
jne.
Vaata ka paketti ggthemes
.
Teemat on aga võimalik ka ise kohandada, täpsustades kohandatavaid
elemente funktsiooni theme()
sees. Kohandatavaid elemente
on palju:
axis.___
telgede elemendid,
legend.___
legendi elemendid,
panel.___
joonise ala elemendid,
plot.___
terve graafiku elemendid
jne.
Iga elemendi väljanägemist (v.a legendi paigutust) saab täpsustada
ühega neljast element
-funktsioonist:
element_blank()
- eemaldab mis tahes elemendi
täielikult,
element_line()
- täpsustab joonte väljanägemist,
element_rect()
- täpsustab piirjoonte ja tausta
väljanägemist,
element_text()
- täpsustab teksti väljanägemist.
Näiteks võib teha sellise teemakihi:
theme(axis.text = element_text(size = 12, # telgede teksti suuruseks 12
color = "grey50"), # ja värviks hallikas
legend.background = element_rect(fill = "transparent"), # legendi taust läbipaistvaks
legend.position = "inside", # legend joonise ala sisse
legend.position.inside = c(0.9, 0.9), # joonise ala sees oleva legendi suhteline asend x- ja y-teljel
panel.background = element_rect(fill = "grey90"), # joonise üldala taustaks hallikas
panel.grid = element_blank(), # kustuta taustaruudustik
plot.subtitle = element_text(hjust = 0.5), # joonda joonise alapealkiri keskele
plot.title = element_text(hjust = 0.5, # joonda joonise pealkiri keskele
face = "bold")) # ja kuva paksus kirjas
Kasutame nüüd objekti p salvestatud graafikut ning lisame sellele loodud teema.
p + theme(axis.text = element_text(size = 12, color = "grey50"),
legend.background = element_rect(fill = "transparent"),
legend.position = "inside",
legend.position.inside = c(0.9, 0.9),
panel.background = element_rect(fill = "grey90"),
panel.grid = element_blank(),
plot.subtitle = element_text(hjust = 0.5),
plot.title = element_text(hjust = 0.5, face = "bold"))
Kui tahame legendi järjekorda muuta, et see vastaks joonise tulpade
värvide järjekorrale, võime teha seda funktsioonis
guides()
.
p + theme(axis.text = element_text(size = 12, color = "grey50"),
legend.background = element_rect(fill = "transparent"),
legend.position = "inside",
legend.position.inside = c(0.9, 0.9),
panel.background = element_rect(fill = "grey90"),
panel.grid = element_blank(),
plot.subtitle = element_text(hjust = 0.5),
plot.title = element_text(hjust = 0.5, face = "bold")) +
guides(fill = guide_legend(reverse = T))
Laadi RStudiosse eelmistes
praktikumides kasutatud küsimustik. Loo ggplot
’i kiht, kus
x-teljel oleks sünniaasta ja y-teljel oleks õpitud aastate arv.
Kuva sünniaasta ja õpitud aastate arvu suhet hajuvusdiagrammil.
Tähista erineva värviga need vastajad, kellel on kvantitatiivsete
meetoditega kogemust, ja need, kellel ei ole. Kasuta kategooriate jaoks
värve “grey45” ja “orange”.
Lisa graafikule pealkiri “Õpitud aastate seos sünniaastaga”, alapealkiri
“ja kokkupuutega kvantitatiivsete meetoditega”, sobivad x- ja y-telje
pealkirjad ning legendi pealkiri “Kogemused kvantitatiivsete
meetoditega”.
Lisa graafikule teema, mis värviks graafiku
tausta värviga “aliceblue” ning joondaks pealkirja ja alapealkirja
keskele.
ggplot
’i üks suuri eeliseid on paneelide funktsioon,
mille abil on võimalik jagada andmestik ühe või mitme tunnuse
alusel alamandmestikeks ning kuvada kõikide
alamandmestike graafikuid korraga ühel joonisel.
Jagame näiteks tehtud graafiku kandidaatide hariduse põhjal
paneelideks. Kasutame selleks funktsiooni facet_wrap()
.
Tunnus, mille alusel paneelid tehakse, lisatakse argumendina funktsiooni
sisse.
ggplot(valimised, aes(y = nimekiri, fill = sugu)) +
geom_bar(position = "dodge") +
scale_fill_brewer(type = "qual", palette = 2, direction = -1) +
scale_y_discrete(limits = naiskandidaatide_osakaal) +
labs(x = "Kandidaatide arv",
y = "",
fill = "Sugu",
title = "Mees- ja naiskandidaatide arv",
subtitle = "Riigikogu valimistel 2023",
caption = "Andmed: https://rk2023.valimised.ee/et/candidates") +
theme(axis.text = element_text(size = 10, color = "grey50"),
legend.background = element_rect(fill = "transparent"),
legend.position = "inside",
legend.position.inside = c(0.9, 0.9),
panel.background = element_rect(fill = "grey90"),
panel.grid = element_blank(),
plot.subtitle = element_text(hjust = 0.5),
plot.title = element_text(hjust = 0.5, face = "bold")) +
guides(fill = guide_legend(reverse = T)) +
facet_wrap("haridus") # Jagame andmestiku hariduse järgi paneelideks. NB! Tunnus jutumärkides!
Või vaatame joonisel hoopis osakaalusid:
ggplot(valimised, aes(y = nimekiri, fill = sugu)) +
geom_bar(position = "fill") + # osakaalude tulpdiagramm
scale_fill_brewer(type = "qual", palette = 2, direction = -1) +
scale_y_discrete(limits = naiskandidaatide_osakaal) +
scale_x_continuous(labels = scales::percent) + # x-telje tekst protsentideks
labs(x = "Osakaal",
y = "",
fill = "Sugu",
title = "Mees- ja naiskandidaatide osakaal",
subtitle = "Riigikogu valimistel 2023",
caption = "Andmed: https://rk2023.valimised.ee/et/candidates") +
theme(axis.text = element_text(size = 10, color = "grey50"),
axis.text.x = element_text(size = 7), # x-telje tekst väiksemas kirjas
legend.background = element_rect(fill = "transparent"),
legend.position = "top", # legend joonise kohale
panel.background = element_rect(fill = "grey90"),
panel.grid = element_blank(),
plot.subtitle = element_text(hjust = 0.5),
plot.title = element_text(hjust = 0.5, face = "bold")) +
guides(fill = guide_legend(reverse = T)) +
facet_wrap("haridus",
labeller = label_wrap_gen()) # murra pikad paneelide pealkirjad eraldi ridadele
Joonist paneelideks jagav tunnus peab olema funktsioonis kas
jutumärkides või kujul ~tunnus
(ilma jutumärkideta). Võib
jagada ka mitme tunnuse järgi. Sel juhul on funktsiooni sees kas
c("esimenetunnus", "teinetunnus")
või
esimenetunnus~teinetunnus
. Alternatiiv funktsioonile
facet_wrap()
on facet_grid()
, mis kuvab
paneele pisut teistmoodi.
Laadi RStudiosse eelmistes
praktikumides kasutatud küsimustik. Loo ggplot
’i kiht, kus
x-teljel oleks sünniaasta ja y-teljel oleks õpitud aastate arv.
Kuva sünniaasta ja õpitud aastate arvu suhet hajuvusdiagrammil.
Tähista erineva värviga need vastajad, kellel on kvantitatiivsete
meetoditega kogemust, ja need, kellel ei ole. Kasuta kategooriate jaoks
värve “grey45” ja “orange”.
Lisa graafikule pealkiri “Õpitud aastate seos sünniaastaga”, alapealkiri
“ja kokkupuutega kvantitatiivsete meetoditega”, sobivad x- ja y-telje
pealkirjad ning legendi pealkiri “Kogemused kvantitatiivsete
meetoditega”.
Lisa graafikule teema, mis värviks graafiku tausta värviga “aliceblue”
ning joondaks pealkirja ja alapealkirja keskele.
Näita erinevatel paneelidel tee- ja
kohvijoojate vastuseid. Jaga kuvatavaid andmeid veel väiksemateks
gruppideks vastavalt lemmikloomale. Võrdle facet_wrap()
ja
facet_grid()
väljundeid.
Võrdle tulemust ChatGPT pakutud koodiga:
Kuna kohandatavaid graafiku elemente on ggplotis väga palju, on sellega võimalik matkida sisuliselt mis tahes graafikute stiile, sh baaspaketi graafikat.
# Sünniaasta karpdiagramm
ggplot(kysimustik,
aes(y = synniaasta)) +
stat_boxplot(geom = "errorbar", # vurrud tuleb joonistada eraldi funktsiooniga
width = 0.5) + # vurru laius 50% oma tavalaiusest
geom_boxplot(outlier.shape = 1, # muuda erindi sümbolit
outlier.size = 2, # tee erindi sümbol suuremaks
fill = "lightgrey") + # määra karbi täitevärv
scale_y_continuous(breaks = seq(1970, 2000, 10)) + # y-skaala 1970-st 2000-ni 10-aastaste intervallidena
labs(y = "") + # y-teljelt tekst ära
theme_classic() +
theme(axis.text.y = element_text(angle = 90, # y-telje tekst 90-kraadise nurga alla
hjust = 0.5), # y-telje tekst joondada sakkidega
axis.text.x = element_blank(), # ära näita x-telje teksti
axis.ticks.x = element_blank(), # ära näita x-telje sakke
panel.background = element_rect(color = "black")) + # joonise alale must kast ümber
xlim(-1, 1) # lisa karbist vasakule ja paremale natuke tühja ruumi
# Lemmiklooma ja sünniaasta karpdiagramm
ggplot(kysimustik,
aes(x = lemmikloom, y = synniaasta)) +
stat_boxplot(geom = "errorbar", # vurrud
width = 0.5) + # vurrud 50% oma tavalaiusest
geom_boxplot(fill = c("lightblue", # kastide värvid
"yellow", # NB! ei ole seotud andmestiku tunnusega
"grey", "red"),
outlier.shape = 1, # erindi kuju
outlier.size = 2) + # erindi suurus
scale_y_continuous(breaks = seq(1970, 2000, 5)) + # y-skaala 1970-st 2000-ni 5-aastaste intervallidena
labs(y = "Sünniaasta") + # muuda y-telje pealkirja
theme_classic() +
theme(panel.background = element_rect(color = "black"))
# Sünniaasta histogramm
ggplot(kysimustik,
aes(x = synniaasta)) +
geom_histogram(binwidth = 5, # sagedusklassi ulatus 5 ühikut (aastat)
boundary = 0, # aitab antud juhul joondada klasse skaala numbritega
color = "black", # klasside ääred mustad
fill = "lightgrey") + # klasside sisu helehall
scale_x_continuous(breaks = seq(1965, 2005, 5)) + # x-skaala 1965-st 2005-ni 5-aastaste intervallidena
labs(title = "Sünniaasta histogramm",
x = "Sünniaasta",
y = "Sagedus") +
theme_classic() +
theme(plot.title = element_text(hjust = 0.5), # graafiku pealkiri keskele
axis.text.y = element_text(angle = 90, # y-telje väärtused 90-kraadise nurga alla
hjust = 0.5)) # y-telje väärtused joondada sakkidega
# Värviline sünniaasta histogramm
ggplot(kysimustik,
aes(x = synniaasta)) +
geom_histogram(binwidth = 10, # sagedusklassi ulatus 10 ühikut
boundary = 0, # joonda klassid skaalaga
color = "grey50", # klasside ääred hallid
fill = c("blue", "purple", "red", "pink", "green")) + # klasside sisu viie erineva värviga
scale_x_continuous(breaks = seq(1960, 2010, 10)) + # x-skaala 1960-st 2010-ni 10-aastaste intervallidena
labs(title = "Sünniaasta histogramm",
x = "Sünniaasta",
y = "Sagedus") +
theme_classic() +
theme(plot.title = element_text(hjust = 0.5), # pealkiri keskele
axis.text.y = element_text(angle = 90, hjust = 0.5)) # y-telje teksti pöörata ja joondada sakkidega
# Ülikoolis õpitud aastate hajuvusdiagramm
ggplot(kysimustik,
aes(y = kaua_opid,
x = seq_along(kaua_opid))) + # vektor, mis koosneb arvudest 1...80
geom_point(shape = 1, # punktide kuju
size = 1.5) + # punktide suurus
labs(x = "Index") + # x-telje pealkiri
theme_classic() +
theme(panel.background = element_rect(color = "black"),
axis.text.y = element_text(angle = 90, # y-telje tekst 90-kraadise nurga alla
hjust = 0.5)) # y-telje tekst joondada sakkidega
# Õpitud aastate ja sünniaasta hajuvusdiagramm
ggplot(kysimustik,
aes(x = synniaasta,
y = kaua_opid)) +
geom_point(shape = 15, # punktide kuju
color = "grey50", # punktide värv
size = 1.5) + # punktide suurus
scale_x_continuous(breaks = seq(1970, 2000, 5)) + # y-skaala 1970-st 2000-ni 5-aastaste intervallidena
labs(x = "Sünniaasta",
y = "Õpitud aastate arv",
title = "Õpitud aastate seos sünniaastaga") +
theme_classic() +
theme(panel.background = element_rect(color = "black"),
axis.text.y = element_text(angle = 90,
hjust = 0.5),
plot.title = element_text(hjust = 0.5))
ggplot(kysimustik,
aes(x = synniaasta,
y = kaua_opid,
color = kogemused_kvant)) + # punktid värvitud andmestiku tunnuse järgi
geom_point(shape = 15,
size = 1.5) +
scale_x_continuous(breaks = seq(1970, 2000, 5)) +
scale_color_manual(name = "Kogemusi kvantmeetoditega", # värvilegendi pealkiri
values = c("grey50", "orange")) + # kategooriate värvid
labs(x = "Sünniaasta",
y = "Õpitud aastate arv",
title = "Õpitud aastate seos sünniaastaga") +
theme_classic() +
theme(panel.background = element_rect(color = "black"),
axis.text.y = element_text(angle = 90,
hjust = 0.5),
plot.title = element_text(hjust = 0.5),
legend.direction = "horizontal", # legend horisontaalne
legend.position = c(0.5, 1), # legend algab x-telje 50% peal ning lõppeb y-telje 100% peal
legend.justification = c(0,1), # legendi asetus
legend.background = element_rect(color = "black")) # legendile must piirjoon ümber
## Warning: A numeric `legend.position` argument in `theme()` was deprecated in ggplot2
## 3.5.0.
## ℹ Please use the `legend.position.inside` argument of `theme()` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
# Tulpdiagramm kvantitatiivsete meetoditega töötamise kogemusest
ggplot(kysimustik,
aes(x = kogemused_kvant)) +
geom_bar(fill = "grey70",
color = "black") +
labs(y = "", x = "") +
scale_y_continuous(breaks = seq(0, 50, 10)) +
theme_classic() +
theme(axis.line.x = element_blank(), # kustuta x-telje joon
axis.text.y = element_text(angle = 90, # y-telje tekst 90-kraadise kaldega
hjust = 0.5)) # y-telje tekst joondatud sakkidega
# Horisontaalne tulpdiagramm
ggplot(kysimustik,
aes(x = kursuse_labimine,
fill = kogemused_kvant)) +
geom_bar(position = "dodge", # kategooriad kõrvuti tulpadena
color = "black") + # tulpade piirjoon must
scale_x_discrete(drop = FALSE) + # jäta alles vastusteta kategooriad
scale_y_continuous(breaks = seq(0, 20, 5)) + # y-teljel väärtused 0st 20ni viiese sammuga
scale_fill_manual(values = c("grey35", "orange"), # määra käsitsi kogemused_kvant kategooriate värvid
name = "Kogemusi kvantmeetoditega") + # nimeta legend ümber
labs(x = "Kursuse läbimise tõenäosus",
y = "Vastanute arv") +
theme_classic() +
theme(axis.line.y = element_blank(), # kustuta ära y-telje joon
axis.ticks.y = element_blank(), # kustuta ära y-telje sakid
legend.position = c(0.5, 0), # legendi suhteline asend x- ja y-telje suhtes
legend.justification = c(0,0), # legendi asetus
legend.direction = "horizontal", # legend horisontaalne
legend.background = element_rect(color = "black")) + # legendile must piirjoon ümber
coord_flip() + # vaheta x- ja y-telg ära
guides(fill = guide_legend(reverse = T)) # pööra legendi kategooriate järjekorda
# Horisontaalne tulpdiagramm osakaaludega
ggplot(kysimustik,
aes(x = kursuse_labimine,
fill = kogemused_kvant)) +
geom_bar(position = position_fill(reverse = TRUE), # absoluutsageduste asemel osakaalud (skaala 0-1), nii et hall "Ei" osa oleks vasakul (vrd lihtsalt position = "fill")
color = "black") +
scale_x_discrete(drop = FALSE) + # näita ka vastusteta kategooriaid
scale_y_continuous(breaks = seq(0, 1, 0.2)) + # y-skaala 0st 1ni intervalliga 0.2
scale_fill_manual(values = c("grey35", "orange"),
name = "Kogemusi kvantmeetoditega") +
labs(x = "Kursuse läbimise tõenäosus",
y = "Vastanute proportsioonid") +
theme_classic() +
theme(axis.line.y = element_blank(), # kustuta y-telje joon
axis.ticks.y = element_blank(), # kustuta y-telje sakid
legend.position = c(0.5, 0),
legend.justification = c(0,0),
legend.direction = "horizontal",
legend.background = element_rect(color = "black")) +
coord_flip()
Kumbki graafikapakett ei ole olemuslikult parem kui teine ja on suur tõenäosus, et joonist, mida saad teha ggplotis, saad teha ka baasgraafikas. Kummaga täpselt töötada, sõltub isiklikest eelistustest, harjumusest ja veidi ka sellest, milliseid graafikuid ja mille jaoks tüüpiliselt kasutatakse. Baasgraafikapaketiga saab enamasti kiiremini oma andmetest ülevaate, ggplot pakub veidi enam võimalusi nt rakendustes või veebilehtedel jooksvateks joonisteks ning on laialtlevinud andmeteaduses. Publitseerimiseks tuleb mõlema paketiga töötades joonistega pisut vaeva näha. Mõlemal paketil on ka terve hulk laiendusi, mis võimaldavad teha asju, millega pakett ise toime ei tule (nt 3D graafikud ggplotis). Asjad, milles ggplotil on siiski selge eelis, on nt legendid, grupeerimine ja paneelid (facets). Loe ka siit.
Väga põhjaliku ülevaate ggplotist ja selle laiendustest leiab nt
lehelt https://github.com/erikgahner/awesome-ggplot2.
Sobiva joonisetüübi valimisel on kindlasti abiks aga leht https://www.data-to-viz.com/.
ggplot2
võimaldab graafikuid värvida kas andmetest
sõltuvalt või sõltumatult. Kui värv sõltub andmetest, täpsustavad seda
argumendid col
ja fill
funktsioonis
aes()
. Sellisel juhul on võimalik värviskaalat muuta
scale
-funktsioonis.
ggplot(data = kysimustik,
aes(x = lemmikjook, fill = lemmikloom)) +
geom_bar() +
scale_fill_manual(values = c("yellow", "green", "blue", "red"))
ggplot(data = kysimustik,
aes(x = lemmikjook, fill = lemmikjook)) +
geom_bar() +
scale_fill_manual(values = c("black", "brown"))
Kui tulpade värv ei sõltu andmestikust, siis saab kasutada argumente
col
ja fill
väljaspool funktsiooni
aes()
.
R-is on võimalik kasutada väga erinevaid olemasolevaid värvipalette või panna kokku täiesti uus, endale meelepärane palett.
Erinevaid värvide nimetusi, mida on võimalik vaikimisi laaditava
graafikapaketiga kasutada, saab vaadata RStudios funktsiooniga
colors()
.
colors()
colors()[1:10] # esimesed 10 värvi
sample(colors(), 10) # suvalised 10 värvi
colors()[!grepl("grey", colors())] # värvid ilma hallideta
sample(colors()[!grepl("grey", colors())], 10) # suvalised 10 värvi ilma hallideta
Aga millised need värvid välja näevad? Võid vaadata näiteks sellelt
lehelt siit
või laadides hulga funktsioone käsuga demo(colors())
.
Samuti näeb värve hõlpsalt, kui kasutada käsku
Lisaks konkreetsetele nimetustele saab kasutada ka RGB-värvimudelit.
Kõik värvid on võimalik kokku segada kolmest põhivärvist: punane, roheline ja sinine. Digitaalseadmetel töötab RGB-värvimudel (R - red, G - green, B - blue), trükkimiseks kasutatakse CMYK-mudelit (C - cyan, M - magenta, Y - yellow, K - key). Kõiki värvispektri värve saab tekitada graafiliselt punase, rohelise ja sinise värvi intensiivsuse muutmisel.
Samuti saab kasutada hex-värvikoode, mis koosnevad trellidest ja kuuest kuueteistkümnendsüsteemis sümbolist. Hex-värvikoodid põhinevad kümnendarvudega väljendatud RGB-mudeli väärtuste teisendamisel kuueteistkümnendsüsteemi.
# Sisend kümnendsüsteemis,
# väljund kuueteistkümnendsüsteemis
rgb(255,255,255,maxColorValue = 255) # white
rgb(0,0,0,maxColorValue = 255) # black
rgb(0,255,0,maxColorValue = 255) # green
rgb(84,255,159,maxColorValue = 255) # seagreen1
rgb(34,139,34,maxColorValue = 255) # forestgreen
Hex-värve saab kombineerida värvipaletiks lugematul hulgal veebilehtedel, nt siin. Oma värvipaletti saab seejärel R-is mingil joonisel kasutada.
# Erinevad viisid värvide täpsustamiseks
minupalett <- c(rgb(147,78,78,maxColorValue = 255),
"#7faf90",
"navyblue",
"#8e7e24")
ggplot(data = kysimustik,
aes(x = aasta, fill = lemmikloom)) +
geom_bar(position = "fill") + # absoluutarvude asemel osakaalud
scale_fill_manual(values = minupalett) + # värvid
scale_y_continuous(labels = scales::percent) + # y-teljel osakaalud näidatud protsentidena
theme(panel.background = element_blank(), # kustuta joonise taust
axis.title = element_blank(), # kustuta telgede nimed
legend.position = "bottom", # aseta legend joonise alla
legend.title = element_blank()) # kustuta legendi pealkiri
Alati ei pea aga ise värvipalette kokku panema, sest sellega võib kulutada väga palju aega ning lõpptulemus ei pruugi sellest paraneda. Seepärast on võimalik kasutada ka mitmeid valmis värvipalette erinevatest pakettidest.
Baasgraafika paketist saab erinevaid palette funktsioonidega
rainbow()
, heat.colors()
,
terrain.colors()
, topo.colors()
ja
cm.colors()
.
RColorBrewer
ggplot(data = kysimustik,
aes(x = aasta,
fill = lemmikloom)) +
geom_bar(position = "fill") +
scale_fill_manual(values = brewer.pal(4,"Set3")) + # määra loomade värvideks käsitsi Breweri "Set3" paletist 4 esimest värvi
scale_y_continuous(labels = scales::percent) +
theme(panel.background = element_blank(),
axis.title = element_blank(),
legend.position = "bottom",
legend.title = element_blank())
ggplot(data = kysimustik,
aes(x = aasta, fill = lemmikloom)) +
geom_bar(position = "fill") +
scale_fill_manual(values = brewer.pal(12, "Set3")[5:8]) + # määra loomade värvideks käsitsi Breweri "Set3" paleti 12 värvist värvid 5-8
scale_y_continuous(labels = scales::percent) +
theme(panel.background = element_blank(),
axis.title = element_blank(),
legend.position = "bottom",
legend.title = element_blank())
ggplot(data = kysimustik,
aes(x = aasta, fill = lemmikloom)) +
geom_bar(position = "fill") +
scale_fill_brewer(type = "qual", palette = 3) + # kasuta ggploti spetsiaalset breweri 'scale'-funktsiooni
scale_y_continuous(labels = scales::percent) +
theme(panel.background = element_blank(),
axis.title = element_blank(),
legend.position = "bottom",
legend.title = element_blank())
colorspace
# väljasta täpsustatud paletist mingi arv hex-värvikoode
sequential_hcl(6, palette = "Red-Yellow")
qualitative_hcl(4, palette = "Dynamic")
diverging_hcl(10, palette = "Cork")
# Kuidas näeksid need värvid eri tüüpi graafikutel välja?
demoplot(sequential_hcl(6, palette = "Red-Yellow"), type = "scatter")
# Programmeerimisoskuse ja sünniaasta suhet
# väljendavad karpdiagrammid,
# kuhu on hajutatult lisatud individuaalsed vaatlused.
# Individuaalsete vaatluste
# värv grupeerib erineva programmeerimisoskusega vastajaid,
# suurus aga viitab ülikoolis õpitud aastate arvule
# (mida suurem täpp, seda kauem õppinud).
ggplot(data = kysimustik,
aes(x = programmeerimisoskus, y = synniaasta)) +
geom_boxplot(fill = "grey90", # karpide värv
outlier.shape = 4) + # erindite kuju
geom_jitter(aes(size = kaua_opid, # suurus andmetest
color = programmeerimisoskus), # värv andmetest
alpha = 0.3, # läbipaistvus
show.legend = FALSE) + # ära näita legendi
scale_x_discrete(limits = levels(kysimustik$programmeerimisoskus)[c(3,2,4,1)], # järjesta tasemed joonisel ümber
labels = c("Ei oska", "Oskan vähe",
"Oskan natuke", "Oskan hästi")) + # muuda joonisel silte
scale_color_discrete_qualitative("Dark2") + # punktide värvipalett ggploti colorspace'i funktsioonist (diskreetsetele kvalitatiivsetele tunnustele)
labs(x = "Programmeerimisoskus",
y = "Sünniaasta") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, # x-telje teksti kaldenurk
hjust = 1), # x-telje teksti joondus
text = element_text(family = "serif")) # muuda fonti
# Programmeerimisoskuse ja sünniaasta suhet
# väljendavad karpdiagrammid,
# kuhu on hajutatult lisatud individuaalsed vaatlused.
# Nii individuaalsete vaatluste värv kui ka suurus
# viitavad ülikoolis õpitud aastate arvule.
ggplot(data = kysimustik,
aes(x = programmeerimisoskus, y = synniaasta)) +
geom_boxplot(fill = "grey90",
outlier.shape = 4) +
geom_jitter(aes(size = kaua_opid,
color = kaua_opid), # värv andmetest
alpha = 0.7,
show.legend = FALSE) +
scale_x_discrete(limits = levels(kysimustik$programmeerimisoskus)[c(3,2,4,1)],
labels = c("Ei oska", "Oskan vähe",
"Oskan natuke", "Oskan hästi")) +
scale_color_continuous_sequential("Reds3") + # punktide värvipalett ggploti colorspace'i funktsioonist (pidevatele tunnustele)
labs(x = "Programmeerimisoskus",
y = "Sünniaasta") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45,
hjust = 1),
text = element_text(family = "serif")) # muuda fonti
Pakett tidyverse
andmete töötlemiseks.