ggplot2 costruisce i grafici a livelli
ggplot2 è il pacchetto di grafici più usato in R, e il motivo per cui molti lo adorano è un'idea di design: la grammatica dei grafici. R base ti dà una funzione per ogni grafico, plot(), hist(), barplot(), ognuna con i suoi argomenti. ggplot2 ti dà invece un piccolo insieme di pezzi componibili, un dataset, una mappatura dalle colonne alle proprietà visive e dei livelli di disegno, che si combinano con + in qualsiasi grafico. Impari la grammatica una volta e ogni nuovo tipo di grafico è la stessa frase con una parola cambiata. In più, le impostazioni predefinite (pannello grigio, assi sensati, legende automatiche) sono presentabili senza alcuno sforzo di stile.
È un pacchetto aggiuntivo, quindi richiede un'installazione una tantum e un caricamento per ogni sessione:
install.packages("ggplot2") # once, on your machine
library(ggplot2) # at the top of every script that uses it
Un'aspettativa da conoscere subito: ggplot2 vuole un data frame (non vettori sparsi), idealmente in formato lungo tidy, cioè una riga per osservazione e una colonna per variabile. Se i tuoi dati sono in formato largo, trasformarli in formato lungo di solito dissolve quello che sembrava un problema di grafici.
Il modello mentale: dati, mappatura, geometria
Ogni ggplot risponde a tre domande, una per parte:
- Dati: quale data frame?
ggplot(mtcars, ...) - Mappatura: quali colonne guidano quali proprietà visive?
aes(x = wt, y = hp) - Geometria: come vanno disegnate le osservazioni?
+ geom_point()
Ecco l'anatomia, pezzo per pezzo:
ggplot(mtcars, aes(x = wt, y = hp)) +
geom_point()
ggplot(mtcars, ...)avvia un grafico i cui dati predefiniti sonomtcars. Da solo disegna un pannello grigio vuoto: non ci sono ancora livelli.aes(x = wt, y = hp)è la mappatura estetica: la posizione orizzontale viene dalla colonnawt, quella verticale dahp. Nota che scrivi nomi di colonna nudi, nonmtcars$wt: la mappatura viene valutata dentro i dati che hai fornito.+ geom_point()aggiunge un livello che disegna ogni riga come un punto. Il+è davvero un'addizione di livelli: il grafico è un oggetto che costruisci poco a poco, e puoi continuare ad aggiungere, un altro geom, le etichette, un tema, ognuno con un altro+.
Eseguilo e otterrai lo stesso grafico a dispersione peso contro cavalli della versione in R base nella guida al grafico a dispersione, su un pannello grigio con linee di griglia bianche. Sostituisci geom_point() con geom_line() e la stessa mappatura diventa un grafico a linee: è la grammatica che fa il suo lavoro.
I geom che userai davvero
Una dozzina di geom copre quasi tutto il lavoro di tutti i giorni:
geom_point() # scatter plot: two numeric variables
geom_line() # line chart: trends over an ordered variable
geom_col() # bar chart from pre-computed heights (needs y)
geom_bar() # bar chart that counts raw rows for you (no y)
geom_histogram() # distribution of one numeric variable (set binwidth)
geom_boxplot() # distributions compared across groups
geom_smooth() # fitted trend line; method = "lm" for straight
I livelli si impilano, ed è qui che ggplot2 inizia a battere R base in espressività: geom_point() + geom_smooth(method = "lm") è un grafico a dispersione con una retta di regressione e una banda di confidenza, in una riga leggibile. Siccome i grafici sono oggetti, puoi anche salvare una base e creare varianti a partire da essa:
p <- ggplot(mtcars, aes(x = wt, y = hp)) + geom_point()
p + geom_smooth(method = "lm") # one variant
p + geom_smooth() # another (loess curve)
Mappare contro impostare: la classica confusione di aes()
L'errore che ogni principiante di ggplot2 commette, di solito nella prima settimana: mettere un colore letterale dentro aes(). La regola è breve, dentro aes() significa "varia con i dati"; fuori significa "impostazione fissa", e le due posizioni fanno cose completamente diverse:
# MAPPING: color varies by a column - each cylinder count gets its own
# color, and a legend appears automatically
ggplot(mtcars, aes(x = wt, y = hp, color = factor(cyl))) +
geom_point(size = 2)
# SETTING: every point is literally steelblue - no legend, no mapping
ggplot(mtcars, aes(x = wt, y = hp)) +
geom_point(color = "steelblue", size = 2)
Ed ecco la trappola vera e propria:
# WRONG: "blue" inside aes() is treated as data, not as a color
ggplot(mtcars, aes(x = wt, y = hp, color = "blue")) +
geom_point()
Questo disegna punti rosa salmone con una legenda la cui unica voce è etichettata "blue". Il motivo: aes() associa colonne a proprietà, quindi color = "blue" crea una finta colonna con una sola categoria il cui valore è ovunque la parola "blue", e ggplot assegna a quella categoria il suo primo colore predefinito, che guarda caso è un salmone rossastro. Se volevi "rendere blu i punti", il colore va fuori dalla mappatura: geom_point(color = "blue"). La stessa regola vale per size, shape, fill e alpha. (Nota anche factor(cyl) nell'esempio di mappatura: cyl è numerico, e avvolgerlo in factor() chiede colori distinti per gruppo invece di una sfumatura di colore continua.)
Etichette, facet e temi
labs() dà un nome a tutto in un unico posto, e un grafico non è finito finché non ha etichette vere:
ggplot(mtcars, aes(x = wt, y = hp, color = factor(cyl))) +
geom_point(size = 2) +
labs(title = "Horsepower vs. weight",
x = "Weight (1000 lbs)",
y = "Horsepower",
color = "Cylinders")
I facet sono la funzionalità di punta di ggplot2: dividono un grafico in piccoli multipli, un pannello per gruppo, con assi condivisi così i pannelli si confrontano onestamente:
ggplot(mtcars, aes(x = wt, y = hp)) +
geom_point() +
facet_wrap(~ cyl)
Compaiono tre pannelli, uno per le auto a 4, 6 e 8 cilindri, disposti in una griglia con il valore del gruppo scritto sopra ogni pannello. In R base è un gioco di prestigio con par(mfrow) e limiti condivisi impostati a mano; qui è una riga. I facet premiano i dati tidy, ed è per questo che ggplot2 si abbina così naturalmente a una pipeline dplyr: filtra e riassumi, poi passa il risultato direttamente a ggplot().
I temi cambiano lo stile di tutto ciò che non rappresenta i dati con una sola chiamata: + theme_minimal() (sfondo bianco pulito), + theme_bw(), + theme_classic() (solo assi, niente griglia), oppure il grigio predefinito. Scegline uno per progetto e sii coerente: un report in cui tutte le figure condividono un tema si legge come un unico documento invece che come un album di ritagli.
Salvare con ggsave(), e quando R base va ancora bene
ggsave() scrive su disco il grafico più recente, deducendo il formato dall'estensione del file:
ggsave("hp-vs-weight.png", width = 8, height = 5) # last plot shown
ggsave("hp-vs-weight.pdf", plot = p, width = 8, height = 5) # a saved object
width e height sono in pollici per impostazione predefinita; impostali esplicitamente, perché la dimensione dei caratteri scala con le dimensioni dell'output e i valori predefiniti raramente corrispondono alla destinazione della figura.
Quanto a quando valga la pena: per un'occhiata di cinque secondi a una variabile durante un'analisi, plot() di R base e simili richiedono meno codice e nessuna dipendenza, e non c'è nessun premio per chi usa ggplot2 ovunque. ggplot2 si guadagna il posto appena una figura coinvolge gruppi, legende, facet o un pubblico: la grammatica scala verso una complessità che i grafici base gestiscono solo con fatica.
Cosa ti porti a casa
- ggplot2 compone ogni grafico con dati + mappatura
aes()+ livelli geom, uniti da+; impari la grammatica una volta e la riusi per ogni tipo di grafico. aes()associa le colonne alle proprietà visive, con nomi di colonna nudi valutati nel tuo data frame.- Dentro
aes()= varia con i dati (e ottiene una legenda); fuori = impostazione fissa.aes(color = "blue")è il bug classico. labs()per i titoli,facet_wrap(~ group)per i piccoli multipli,theme_minimal()e simili per lo stile,ggsave()con dimensioni esplicite per esportare.- Occhiata veloce in solitaria: R base. Gruppi, facet o un pubblico: ggplot2.
Con questo si chiude il capitolo sui grafici: da qui, il passo successivo naturale sono le statistiche descrittive, per dare dei numeri alle forme che questi grafici rivelano.
Domande frequenti
Cos'è ggplot2 in R?
ggplot2 è il pacchetto di grafici più popolare di R. Invece di una funzione per ogni tipo di grafico, componi ogni grafico con gli stessi tre pezzi, un data frame, una mappatura aes() dalle colonne alle proprietà visive e uno o più livelli geom_*(), uniti con +. Fa parte del tidyverse.
Come si installa ggplot2?
Esegui install.packages("ggplot2") una volta, poi library(ggplot2) in cima a ogni script che lo usa. L'installazione mette il pacchetto sul tuo computer; library() lo carica nella sessione corrente.
Cosa fa aes() in ggplot2?
aes() associa le colonne dei tuoi dati alle proprietà visive: aes(x = wt, y = hp, color = factor(cyl)) dice che la posizione orizzontale viene da wt, quella verticale da hp e il colore dei punti dal numero di cilindri. Tutto ciò che sta dentro aes() varia con i dati; tutto ciò che sta fuori è un'impostazione fissa.
Perché i miei punti ggplot non hanno il colore che ho chiesto?
Hai messo il colore dentro aes(): aes(color = "blue") non imposta un colore, mappa una categoria inventata chiamata "blue", quindi ggplot sceglie il suo colore predefinito e aggiunge una legenda. Per impostare un colore letterale, mettilo fuori dalla mappatura: geom_point(color = "blue").