Grammar of Graphics (ggplot2)

Knihovna ggplot2: implementace Grammar of Graphics (Leland Wilkinson), http://docs.ggplot2.org/

Krásný „tahák“ s přehledem základních možností: http://www.rstudio.com/resources/cheatsheets/ (Data Visualization Cheat Sheet)

Přehledně zpracované příklady grafů v R: http://www.cookbook-r.com/Graphs/

Grafy a obrázky zadáváme pomocí „podstatných jmen“, „přídavných jmen“ a „sloves“.

Vycházíme z dat v dobře uspořádaném dataframe (formát tidy data). Faktorové proměnné musejí být v dataframe skutečně označeny jako faktorové (viz kapitola 2. Faktorové proměnné), abychom znázornili, že se jedná o diskrétní kategorie, které nám mohou např. rozdělovat data do skupin. Pozor! Použití faktorových proměnných je obzvláště nutné u číselných hodnot, které mají být chápány jako diskrétní kategorie. Pokud máme např. proměnnou PořadíČtení s hodnotami 1 a 2, při jejím použití na x-ovou osu grafů může dojít k vytvoření reálné spojité osy, pokud je proměnná typu numeric. Jestliže ji převedeme na faktorovou proměnnou, budou správně vytvořeny dvě diskrétní hodnoty.

Vše by mělo být v datech hezky pojmenované, protože se ze jmen automaticky stávají popisky grafů. Tedy raději proměnná ‘Pohlaví’ než ‘pohl’, hodnoty spíše ‘muž’ a ‘žena’ než 0 a 1.

Dále přidáváme tzv. vzhled, estetiku (aesthetics), kde určujeme, co z dat se má mapovat na osy x a y, co má určovat velikost, tvar a barvu. Legendy (popisky) se tvoří podle těchto vlastností automaticky.

Pomocí facets je možné rozdělit obrázek do více panelů na základě jedné nebo více diskrétních kategorií (faktorové proměnné). Jedná se tedy opět o jistou formu aesthetics, kdy se automaticky zjistí, kolika různých hodnot daná proměnná nabývá, podle toho se data rozdělí do příslušných skupin a pro každou se vykreslí samostatný a přehledně popsaný graf.

Důležité je určit druh tvaru (geoms), jakým se mají data znázornit. Zda to mají být body, čáry, sloupce, histogramy, odhady hustoty pravděpodobnosti, krabicové grafy apod. V rámci jednoho zobrazení můžeme přidat současně klidně více různých geoms, pokud to dává smysl.

Aby toho nebylo málo, připojit můžeme statistické ukazatele (stats). Může se jednat například o regresi (automatické vykreslení pásu 95% pravděpodobnosti výskytu je samozřejmostí), zobrazení středu dat včetně případného 95% intervalu spolehlivosti, ale také třeba elipsy znázorňující 2D oblast výskytu 95 % nejčastějších hodnot. To vše pomocí jednoduchého příkazu, což ušetří mnoho náročné práce.

Dále je možné přidávat vlastní popisky (labels), měnit souřadnicový systém (coordinate systems) a volit různá témata (themes), protože základní vzhled je sice hezký, ale občas potřebujeme jednodušší zobrazení.

Instalace knihovny ggplot2

Pokud ještě není knihovna ggplot2 nainstalována, učiníme tak příkazem (stačí provést jednou)

install.packages("ggplot2")

Před použitím knihovny je potřeba ji nejdříve zavést příkazem (nutné vždy po startu R)

library(ggplot2)

Příklad 1

Stáhnout soubor s daty: modre_cervene.csv.

tabulka <- read.csv("modre_cervene.csv")

ggplot(data = tabulka, aes(x = x, y = y)) +
    geom_point()

ggplot(data = tabulka, aes(x = x, y = y, color = group)) +
    geom_point()

ggplot(data = tabulka, aes(x = x, y = y, shape = group)) +
    geom_point()

ggplot(data = tabulka, aes(x = x, y = y, shape = group, color = group)) +
    geom_point()

ggplot(data = tabulka, aes(x = x, y = y, shape = group, color = group)) +
    geom_point(size = 3)

ggplot(data = tabulka, aes(x = x, y = y, shape = group, color = group)) +
    geom_point(size = 3) +
    stat_smooth(method = "lm")   # lineární regrese vč. 95% pásů

Příklad 2

Příprava dat

Stáhnout soubor s daty: vokalyhz.txt.

data <- read.table("vokalyhz.txt", header = TRUE, sep = ",")
str(data) # Je vidět, že Vowel a Sex jsou faktorové, což je dobré. SpeakerID by ale také měl být faktor.
## 'data.frame':    3000 obs. of  7 variables:
##  $ Vowel    : Factor w/ 5 levels "a","e","i","o",..: 1 1 1 1 1 1 1 1 1 1 ...
##  $ Sex      : Factor w/ 2 levels "f","m": 1 1 1 1 1 1 1 1 1 1 ...
##  $ F0.mean  : num  212 219 252 244 231 ...
##  $ SpeakerID: int  1 2 3 4 7 8 10 11 12 13 ...
##  $ F1_Hz    : num  819 713 748 791 788 ...
##  $ F2_Hz    : num  1354 1393 1495 1754 1622 ...
##  $ F3_Hz    : num  2595 2634 2497 2443 2961 ...
data$SpeakerID <- factor(data$SpeakerID)

# bylo by hezké přejmenovat hodnoty Sex
levels(data$Sex)     # původní názvy
## [1] "f" "m"
levels(data$Sex) <- c("žena", "muž")

# a ještě přejmenovat proměnné
library(dplyr)
data <- data %>% rename(Vokál = Vowel, Pohlaví = Sex)

str(data)  # výrazně hezčí forma
## 'data.frame':    3000 obs. of  7 variables:
##  $ Vokál    : Factor w/ 5 levels "a","e","i","o",..: 1 1 1 1 1 1 1 1 1 1 ...
##  $ Pohlaví  : Factor w/ 2 levels "žena","muž": 1 1 1 1 1 1 1 1 1 1 ...
##  $ F0.mean  : num  212 219 252 244 231 ...
##  $ SpeakerID: Factor w/ 75 levels "1","2","3","4",..: 1 2 3 4 7 8 10 11 12 13 ...
##  $ F1_Hz    : num  819 713 748 791 788 ...
##  $ F2_Hz    : num  1354 1393 1495 1754 1622 ...
##  $ F3_Hz    : num  2595 2634 2497 2443 2961 ...

Obrázky

ggplot(data = data, aes(x = F1_Hz)) +  # volba dat a nejjednodušší aesthetics: na ose x jsou hodnoty F1_Hz
    geom_histogram()                   # přidání geom: histogram

Pro začátek to není špatné, ale máme všechny vokály v jednom histogramu. Co je zkusit odlišit barvou? Přidáme tedy pokyn do aesthetitcs, ať barvu nastaví podle Vokál.

ggplot(data = data, aes(x = F1_Hz, color = Vokál)) +  # ať nastaví barvu podle vokálu Vokál
    geom_histogram()                   # histogram

Aha, tím se nastavila ale jen barva okraje. Chtělo by to výplň. Podíváme se do “Cheat Sheet” a vidíme, že lze u histogramu nastavit také fill.

ggplot(data = data, aes(x = F1_Hz, fill = Vokál)) +  # raději tedy barvu výplně podle vokálu Vokál
    geom_histogram()                   # histogram

Nebylo by hezší zobrazit spíše odhad hustoty pravděpodobnosti (tzv. kernel density function)?

ggplot(data = data, aes(x = F1_Hz, color = Vokál)) +
    geom_density()                   # odhad hustoty pravděpodobnosti

ggplot(data = data, aes(x = F1_Hz, fill = Vokál)) + geom_density(alpha = 0.5)

Hezké, ale pořád máme muže a ženy dohromady. Udělal bych raději pro každou skupinu obrázek zvlášť, na řadu přicházejí facets.

ggplot(data = data, aes(x = F1_Hz, fill = Vokál)) +
    geom_density(alpha = 0.5) +
    facet_grid(. ~ Pohlaví)   # formát: řádky ~ sloupce. Tečka znamená "nerozdělovat". Zde tedy říkáme, že chceme 1 řádek a sloupce podle Pohlaví.

Vidíme, že ženy jsou výše. Když to jde tak snadno, co se vrátit k histogramům a sloupce udělat podle vokálu a řádky podle pohlaví?

ggplot(data = data, aes(x = F1_Hz, fill = Vokál)) +
    geom_histogram() +
    facet_grid(Pohlaví ~ Vokál)   # formát: řádky ~ sloupce.