Pakett ggplot2

ggplot2

Pakett ggplot2:

  • võimaldab teha vähese vaevaga ilusaid jooniseid,
  • toimib andmetabelitega ehk data frame’idega (!),
  • töötab kihtide põhimõttel, lisatavate kihtide arv on lõpmatu,
  • sisaldab funktsiooni 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.

# Laadi andmestik
# tabel on csv-formaadis, tabelil on päiserida tulpade nimedega (header), 
# tulpasid eraldab tabulaator ("\t") ja faili kodeering on UTF-8
valimised <- read.delim("data/kandidaadid_2023.csv", header = T, sep = "\t", encoding = "UTF-8")

ggploti graafikud ja esquisse()

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

  1. valida esmalt sobiva andmestiku, vaadata, milline see välja näeb, muuta tulbanimesid jm,
  2. sikutada graafikule tunnused, mille jaotumist tahetakse visualiseerida,
  3. muuta graafiku omadusi (värvid, sildid, teksti suurus jm),
  4. kopeerida graafiku koodi ja/või salvestada graafik faili.
# 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

  1. kandidaatide vanuse jaotumist (kui vanad olid kandidaadid?)
  2. kandidaatide vanuse jaotumist vastavalt valimisnimekirjale (kui vanad olid erinevate nimekirjade kandidaadid?)
  3. kandidaatide vanuse jaotumist vastavalt vanusele (kas meeskandidaadid olid vanemad kui naiskandidaadid?)
  4. kandidaatide soo jaotumist (kui palju oli mehi ja naisi?)
  5. kandidaatide soo jaotumist vastavalt valimisnimekirjale (kas mõnes erakonnas oli rohkem naisi?)
  6. kandidaatide häältesaagi jaotumist (kui palju hääli saadi?)
  7. kandidaatide häältesaagi jaotumist vastavalt valimisnimekirjale (kui palju hääli said erinevate valimisnimekirjade kandidaadid?)
  8. kandidaatide häältesaagi jaotumist vastavalt vanusele (kas vanemad/nooremad kandidaadid said rohkem hääli?)
  9. kandidaatide häältesaagi jaotumist vastavalt soole (kas mehed/naised said rohkem hääli?)

1. kiht: andmed ja tunnused (data & mapping)

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.

# Joonistatakse ainult tühi palett.
ggplot(data = valimised)

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-teljel (x = ...),
  • y-teljel (y = ...),
  • värvi abil (color = ...),
  • täitevärvi abil (fill = ...),
  • kujundi abil (shape = ...),
  • suuruse abil (size = ...),
  • läbipaistvuse abil (alpha = ...),
  • joone tüübi abil (linetype = ...)
  • jne.

Ü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.

ggplot(data = valimised,
       mapping = aes(x = sugu))

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.

ggplot(valimised,
       aes(x = sugu))

Harjuta

Laadi RStudiosse eelmistes praktikumides kasutatud küsimustik. Loo ggplot’i kiht, kus x-teljel oleks sünniaasta ja y-teljel oleks õpitud aastate arv.

2. kiht: graafiku tüüp (geom)

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),
  • jne.
# 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:

ggplot() +
  geom_bar(data = valimised,
           aes(x = sugu))

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")

Harjuta

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.

3. kiht: tunnuste väljanägemine graafikul (scale)

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

  1. eri kategooriate tulbad võiksid olla hoopis üksteise kõrval (geom_bar(position = "dodge")) või et
  2. vaatleme absoluutsageduste asemel hoopis proportsioone, st seda, kui suured on ühe või teise nimekirja mees- ja naiskandidaatide osakaalud (geom_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.

Harjuta

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”.

4. kiht: selgitavad tekstid (labs)

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")

Harjuta

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”.

5. kiht: graafiku üldine väljanägemine (theme)

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))

Harjuta

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.

6. kiht: paneelid (facets)

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.

Harjuta

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:

Eelmiste kordade graafikud

Kuna kohandatavaid graafiku elemente on ggplotis väga palju, on sellega võimalik matkida sisuliselt mis tahes graafikute stiile, sh baaspaketi graafikat.

Karpdiagramm

# 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"))

Histogramm

# 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

Hajuvusdiagramm

# Ü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

# 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()

Baasgraafika või ggplot2?

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.

Ggploti lisamaterjale ja laiendusi


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/.

Värvid ja värvipaletid

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().

ggplot(data = kysimustik,
       aes(x = lemmikjook)) +
  geom_bar(fill = c("black", "brown"))

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()).

demo(colors())

Samuti näeb värve hõlpsalt, kui kasutada käsku

scales::show_col(colors(), cex_label = 1)

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.

col2rgb("white")
col2rgb("black")
col2rgb("green")
col2rgb("seagreen1")
col2rgb("forestgreen")

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 paletid

Baasgraafika paketist saab erinevaid palette funktsioonidega rainbow(), heat.colors(), terrain.colors(), topo.colors() ja cm.colors().

# Funktsioonis saab täpsustada
# väljastatavate värvikoodide arvu
rainbow(10)
heat.colors(10)
terrain.colors(6)
topo.colors(7)
cm.colors(4)

RColorBrewer

# install.packages("RColorBrewer")
library(RColorBrewer)
display.brewer.all() # valmis paletid

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

# install.packages("colorspace")
library(colorspace)
hcl_palettes(plot = TRUE) # valmis paletid

# 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")

demoplot(qualitative_hcl(4, palette = "Dynamic"), type = "bar")

demoplot(diverging_hcl(10, palette = "Cork"), type = "lines")

# 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

Järgmisel korral

Pakett tidyverse andmete töötlemiseks.