Grammar of Graphics

Fondamenti di ggplot2

Marco Chiapello

Perché Visualizzare? Il Datasaurus Dozen

Le statistiche riassuntive non bastano!

13 dataset con IDENTICHE statistiche:

  • Media X: ~54.26
  • Media Y: ~47.83
  • Deviazione Standard X: ~16.76
  • Deviazione Standard Y: ~26.93
  • Correlazione: ~-0.06

Senza visualizzare, sembrano lo stesso dataset!

Con la visualizzazione, la verità emerge…

# Install & carica
install.packages("datasauRus")
library(datasauRus)

# Esplora i dati
head(datasaurus_dozen)

# Verifica statistiche identiche
library(dplyr)
datasaurus_dozen %>% 
  group_by(dataset) %>% 
  summarise(
    mean_x = mean(x),
    mean_y = mean(y),
    cor_xy = cor(x, y)
  )

Il Datasaurus Dozen Visualizzato

library(ggplot2)
library(datasauRus)

ggplot(datasaurus_dozen, aes(x = x, y = y, color = dataset)) +
  geom_point() +
  facet_wrap(~ dataset, ncol = 4) +
  theme_minimal() +
  theme(legend.position = "none")

Pattern completamente diversi:

  • 🦕 Dinosauro
  • ⭐ Stella
  • ⭕ Cerchi
  • ❌ X
  • Linee verticali/orizzontali
  • … e molti altri!

La Lezione

Mai fidarsi solo delle statistiche!

La visualizzazione rivela pattern, outlier, distribuzioni che i numeri nascondono.

Anscombe’s Quartet: Il Predecessore

Prima del Datasaurus, c’era Anscombe (1973)

4 dataset con statistiche IDENTICHE:

  • Media X: 9.0
  • Media Y: 7.5
  • Varianza X: 11.0
  • Varianza Y: 4.12
  • Correlazione: 0.816
  • Equazione regressione: y = 3 + 0.5x
# Built-in in R
data(anscombe)

Ma visualizzati sono completamente diversi:

  1. Relazione lineare perfetta
  2. Relazione non-lineare (quadratica)
  3. Relazione lineare con outlier
  4. Outlier influente (high leverage)

Il messaggio

Sempre visualizzare prima di analizzare statisticamente!

Best Practices per Pubblicazioni Scientifiche

Perché le visualizzazioni contano nella scienza?

  • I grafici sono strumenti di scoperta e comunicazione
  • Permettono di esplorare pattern nei dati
  • Comunicano risultati in modo più efficace del testo
  • Devono essere accurati, onesti e chiari

Principio fondamentale: Un grafico deve rispettare i dati e aiutare il lettore a comprenderli

Percezione Visiva: Come Leggiamo i Grafici

Gerarchia percettiva (dal più al meno accurato):

  1. Posizione lungo scala comune (scatter plot, bar chart)
  2. Posizione lungo scale non allineate (small multiples)
  3. Lunghezza, direzione, angolo (slope charts)
  4. Area (bubble charts) - più difficile da giudicare
  5. Volume, curvatura (3D charts) - evitare!
  6. Colore - saturazione, tonalità

Implicazione pratica: Usa posizione quando possibile, evita 3D e pie charts complessi

Riferimento: Cleveland & McGill (1984), Ware (2008)

Principio dell’Inchiostro Proporzionale

The Principle of Proportional Ink (Wilke, 2019)

La quantità di “inchiostro” usata per rappresentare un valore deve essere proporzionale al valore stesso

Esempi comuni di violazione:

  • Bar chart con asse y che non parte da zero → esagera differenze
  • Bubble chart con raggio (non area) proporzionale al valore → distorce percezione
  • Pie chart in 3D → prospettiva distorce proporzioni

Best practice:

  • Bar chart → sempre asse y da zero
  • Bubble chart → area ∝ valore, non raggio
  • Evita 3D decorativo

Onestà e Integrità dei Dati

Errori comuni che distorcono la verità:

1. Assi manipolati - EVITA - asse y troncato senza indicazione chiara

2. Cherry-picking - Mostrare solo subset favorevole

3. Dual y-axes - Scale diverse creano correlazioni spurie → Evitare

4. Binning arbitrario - Bin width cambia la storia → mostra più versioni

Uso Efficace del Colore

Principi per l’uso del colore:

1. Accessibilità
- Color blindness
~8% uomini, ~0.5% donne hanno daltonismo
- Soluzione: palette colorblind-safe (viridis, ColorBrewer)

scale_color_viridis_d()           # discreto
scale_color_viridis_c()           # continuo
scale_color_brewer(palette = "Set2")  # ColorBrewer

2. Tipi di scale cromatiche
- Qualitativa: categorie non ordinate (Set1, Set2, Dark2)
- Sequenziale: valori ordinati (Blues, Greens, Viridis)
- Divergente: dati con punto medio (RdBu, BrBG) - es. correlazioni

3. Evita semaforo (rosso-giallo-verde) - non accessibile

Codifica Ridondante

Redundant Coding (Wilke, Ch. 20)

Codifica la stessa informazione in modi multipli per robustezza:

Vantaggi:

  • Leggibile anche in stampa B/N
  • Accessibile per daltonici
  • Più facile da interpretare

Figure Multi-Panel

Best practices per figure composite:

1. Small multiples (faceting) - stessi assi

2. Composizione con patchwork

Regole:

  • Etichette consistenti: (A), (B), (C) o a), b), c)
  • Font size: devono essere leggibili alla dimensione finale
  • Aspect ratio: mantieni proporzioni ragionevoli
  • Caption completo: ogni panel deve essere comprensibile

Titoli, Didascalie e Annotazioni

Anatomia di una figura pubblicabile:

    title = "Breve e informativo",         # opzionale per paper
    subtitle = "Dettagli aggiuntivi",      # opzionale
    x = "Variabile esplicativa [unità]",   # SEMPRE con unità
    y = "Variabile risposta [unità]",      # SEMPRE con unità
    color = "Gruppo",                       # etichetta legenda
    caption = "Fonte: Studio XYZ (2024)"   # fonte dati

Per pubblicazioni scientifiche:

  • Caption nella rivista, non nel grafico stesso
  • Asse labels: chiari, con unità di misura
  • Legend: auto-esplicativa
  • Font size: 8-12pt nella versione finale (usa theme(text = element_text(size = 12)))

Bilanciare Dati e Contesto

Data-ink ratio (Tufte, 1983)

Massimizza la proporzione di “inchiostro” dedicato ai dati

Rimuovi elementi non essenziali: Ma non esagerare!

  • Griglia maggiore: utile per leggere valori
  • Assi: necessari per interpretazione
  • Legend: essenziale per categorie

Obiettivo: Chiarezza, non minimalismo estremo

Gestione dell’Overlapping

Soluzioni per punti sovrapposti:

1. Trasparenza (alpha)

2. Jittering

3. 2D density / Heatmap

4. Contour plots

Scegli in base a: numero punti, messaggio da comunicare, audience

Dimensione degli Assi e Leggibilità

“Use Larger Axis Labels” (Wilke, Ch. 24)

Problema comune: Font troppo piccoli nella versione finale

Test pratico:

  • Salva a dimensione finale (es. 6×4 pollici per column width)
  • Stampa o visualizza al 100%
  • Deve essere leggibile senza sforzo

Salvare Grafici per Pubblicazione

Formati e parametri corretti:

Linee guida:

  • Journal: PDF/EPS (vettoriale) o TIFF 600dpi
  • Presentazioni: PNG 300dpi
  • Dimensioni: verifica Author Guidelines

Checklist Finale per Figure Scientifiche

Prima di sottomettere, verifica:

Accuratezza

Chiarezza

Professionalità

Risorse Fondamentali

Libri essenziali:

Articoli scientifici:

  • Cleveland & McGill (1984) - Percezione grafica
  • Rougier et al. (2014) - “Ten Simple Rules for Better Figures”

Online:

Cosa significa “gg” in ggplot2?

Grammar of Graphics

Framework teorico di Leland Wilkinson (1999)

  • Sistema per progettare visualizzazioni
  • Non su cosa è bello o best practices
  • Focus: come costruire qualsiasi visualizzazione
  • Base per: ggplot2, Tableau, Vega-lite

La filosofia

Decostruire i grafici in componenti riutilizzabili

Tutti i grafici (barre, linee, scatter) condividono elementi comuni:

  • Scale
  • Coordinate
  • Trasformazioni statistiche
  • Posizioni
  • Geometrie

Mix & Match: Combina i componenti per creare qualsiasi visualizzazione!

I 7 componenti principali

I layer si sovrappongono dal basso verso l’alto

Template base di ggplot2

Struttura completa di un plot ggplot2:

ggplot(data = <DATA>, mapping = aes(<MAPPINGS>)) + 
  <GEOM_FUNCTION>(
     mapping = aes(<MAPPINGS>),
     stat = <STAT>, 
     position = <POSITION>
  ) +
  <COORDINATE_FUNCTION> +
  <FACET_FUNCTION> +
  <SCALE_FUNCTION> +
  <THEME_FUNCTION>

In pratica (esempio reale):

ggplot(mpg, aes(x = displ, y = hwy)) +       # Data + Aesthetics
  geom_point(aes(color = class)) +            # Geometries
  facet_wrap(~ year) +                        # Facets
  scale_color_brewer(palette = "Set1") +      # Scales
  coord_cartesian(ylim = c(10, 45)) +         # Coordinates
  theme_minimal()                             # Theme

Layer 1: Data

Il dataset che vogliamo visualizzare

Importante

ggplot2 lavora meglio con dati “tidy”!

Dati NON-Tidy: Esempio da evitare

Dati in formato “wide” (NON funziona con ggplot2):

country 1999_cases 1999_pop 2000_cases 2000_pop
Afghanistan 745 19987071 2666 20595360
Brazil 37737 172006362 80488 174504898
China 212258 1272915272 213766 1280428583

Problemi:

  • ❌ Le colonne contengono valori (anni), non variabili
  • ❌ Più variabili per riga (cases e pop mescolati)
  • ❌ Impossibile mappare direttamente

Soluzione: Trasformare in formato “long”

Dati Tidy: Versione corretta

Stessi dati in formato “long” (✅ funziona con ggplot2):

country year cases population
Afghanistan 1999 745 19987071
Afghanistan 2000 2666 20595360
Brazil 1999 37737 172006362
Brazil 2000 80488 174504898
China 1999 212258 1272915272
China 2000 213766 1280428583

Vantaggi:

  • ✅ Ogni colonna = una variabile (country, year, cases, population)
  • ✅ Ogni riga = una osservazione (paese-anno)
  • ✅ Ogni cella = un singolo valore

Layer 2: Aesthetics - Il Ponte tra Dati e Visual

Definizione formale di “Aesthetic”:

Un’estetica è qualsiasi proprietà visuale degli oggetti in un plot che può essere controllata per trasmettere informazione

Il concetto chiave: Un grafico statistico è una mappatura (mapping) da variabili dei dati ad attributi estetici di oggetti geometrici

Aesthetics fondamentali:

  • x, y - Posizione nello spazio 2D
  • color - Colore di bordi/linee/punti
  • fill - Colore di riempimento
  • size - Dimensione (area punti)
  • shape - Forma dei punti
  • alpha - Trasparenza/opacità
  • linetype - Tipo di linea

La funzione aes():

Il “motore” delle mappature estetiche

aes(x = displ, 
    y = hwy, 
    color = class)

Crea il link esplicito tra colonne del dataset e proprietà visive

Aesthetics: Mapping vs Setting

La dicotomia fondamentale di ggplot2:

MAPPING (dentro aes())

Proprietà visiva dipende dai dati

ggplot(mpg, aes(x = displ, 
                y = hwy, 
                color = class)) +
  geom_point()

Risultato:

  • Colore varia per ogni punto
  • Legenda creata automaticamente
  • Scala colori applicata automaticamente
  • Rappresenta dati

Quando usare: Per visualizzare una variabile del dataset

SETTING (fuori aes())

Proprietà visiva costante

ggplot(mpg, aes(x = displ, 
                y = hwy)) +
  geom_point(color = "blue", 
             size = 3, 
             alpha = 0.6)

Risultato:

  • Tutti i punti blu, stessa dimensione
  • Nessuna legenda
  • Nessuna scala
  • Scelta stilistica

Quando usare: Per impostare uno stile fisso

Aesthetics: L’Errore Comune

Perché aes(color = "blue") NON produce punti blu?

# ❌ ERRORE COMUNE - Non produce punti blu!
ggplot(mpg, aes(x = displ, y = hwy)) +
  geom_point(aes(color = "blue"))

La logica formale dietro questo comportamento:

  1. Interpretazione: aes() interpreta tutto come dati, non come istruzioni di stile
  2. Creazione pseudo-variabile: "blue" diventa una variabile temporanea con valore costante "blue" per ogni riga
  3. Trattamento categorico: Questa “variabile” ha un solo livello: la stringa "blue"
  4. Invocazione scala: scale_color_discrete() viene applicata automaticamente
  5. Mappatura colore: La scala assegna il primo colore della palette (tipicamente rosso) al livello "blue"
  6. Legenda: Viene generata una legenda che mostra: livello dati = "blue" → colore = rosso

Principio chiave

aes() è uno spazio sacro riservato esclusivamente al mapping dati-visual. Qualsiasi valore al suo interno viene interpretato come parte dello spazio dati, non dello spazio stilistico.

Aesthetics: Guida Completa alle Proprietà Visive

Aesthetic Proprietà Controllata Tipo Dati Geoms Comuni Note Importanti
x, y Posizione sugli assi Continuo, Discreto Tutti Le estetiche più fondamentali
color Colore bordi/linee/punti Continuo, Discreto geom_point, geom_line Per shape 21-25: controlla il bordo
fill Colore riempimento Continuo, Discreto geom_bar, geom_boxplot Solo per geom con area interna
size Area punti, dimensione testo Continuo geom_point, geom_text Scala l’area, non il raggio. Evitare per variabili discrete
linewidth Spessore linee Continuo geom_line, geom_smooth Introdotto in ggplot2 3.4.0 per controllo esplicito
shape Forma punti Discreto geom_point Max 6 categorie. Shapes 0-20: solidi; 21-25: con bordo+fill
alpha Trasparenza (0-1) Continuo Tutti Strumento primario per overplotting
linetype Pattern linea Discreto geom_line, geom_path Max 6 categorie (solid, dashed, dotted, etc.)
group Raggruppamento dati Discreto geom_line, geom_smooth Cruciale per aggregazione corretta (es. time series)
label Contenuto testo Character geom_text, geom_label Specifica il testo da visualizzare

Percezione visiva

Posizione > Lunghezza > Angolo > Area > Colore. Usa x/y per variabili più importanti, color/size per secondarie.

Color vs Fill

Due aesthetic per il colore:

color - Bordi, linee, punti (contorni):

geom_point(color = "red")      # punti rossi
geom_line(color = "blue")      # linea blu
geom_bar(color = "black")      # bordo barre nero

fill - Riempimento interno (aree):

geom_bar(fill = "steelblue")           # barre riempite
geom_boxplot(fill = "lightgreen")      # box riempiti
geom_violin(fill = "orange")           # violin riempiti

Entrambi insieme:

geom_bar(fill = "steelblue", color = "black", linewidth = 1)
# → Barre blu con bordo nero

Regola pratica: Geoms con area interna usano fill, geoms 1D usano color

Layer 3: Geometries (Geometrie)

Forme visive che rappresentano i dati:

1D (una variabile):

  • geom_histogram(), geom_density(), geom_dotplot()

2D (due variabili):

  • geom_point() - Scatter plot
  • geom_line() - Linee connesse
  • geom_smooth() - Linea di tendenza
  • geom_boxplot(), geom_violin() - Distribuzioni

Conteggi:

  • geom_bar(), geom_col() - Barre

Multipli layer: Combina più geometrie nello stesso grafico!

Layer 3: Geometries

Ogni geom ha parametri specifici:

# Point: shape, size, alpha
geom_point(shape = 16, size = 3, alpha = 0.7)

# Line: linetype, linewidth
geom_line(linetype = "dashed", linewidth = 1)

# Smooth: method, se (standard error)
geom_smooth(method = "lm", se = TRUE)

I geom ereditano le aesthetics da ggplot() ma possono avere le proprie:

ggplot(mpg, aes(x = displ, y = hwy)) +  # aesthetics globali
  geom_point(aes(color = class)) +       # solo per i punti
  geom_smooth()                           # usa solo x e y

Layer 4: Facets

Suddividi i dati in sottografici multipli (piccoli multipli)

Potente per:

  • Confrontare sottogruppi
  • Evitare sovrapposizione (decluttering)
  • Il cervello riusa i pattern visivi tra panel
  • Esplorare interazioni tra variabili

Layer 4: Facets

Opzioni di personalizzazione:

# Scale libere per ogni panel
facet_wrap(~ class, scales = "free")     # entrambi liberi
facet_wrap(~ class, scales = "free_x")   # solo x libero
facet_wrap(~ class, scales = "free_y")   # solo y libero

# Etichette personalizzate
facet_wrap(~ class, labeller = label_both)  # mostra "class: suv"

# Margini
facet_grid(drv ~ cyl, margins = TRUE)  # aggiunge totali marginali

Best practice: Mantieni scale fisse quando possibile per facilitare confronti!

Layer 5: Stats (Trasformazioni)

Trasformazioni sui dati prima di plottare:

Stats comuni:

  • stat_bin() - Istogrammi (conta in bin)
  • stat_count() - Bar chart (conta osservazioni)
  • stat_smooth() - Modelli (lm, loess, gam)
  • stat_boxplot() - Quartili e outlier
  • stat_summary() - Funzioni custom (media, mediana, etc.)

Ogni geom ha uno stat di default:

geom_histogram()  # stat = "bin"
geom_bar()        # stat = "count"
geom_smooth()     # stat = "smooth"

Layer 5: Stats

Usare stats direttamente (invece di geoms):

# Equivalenti
geom_bar(stat = "count")
stat_count(geom = "bar")

# Cambio di stat
geom_bar(stat = "identity")  # usa valori y così come sono

# Summary personalizzate
stat_summary(fun = mean, geom = "point", size = 4)
stat_summary(fun.data = mean_se, geom = "errorbar")

Variabili calcolate: Gli stats creano nuove variabili accessibili con after_stat():

# Istogramma con densità invece di conteggi
geom_histogram(aes(y = after_stat(density)))

Scoprire le variabili calcolate

Per vedere quali variabili sono disponibili con after_stat(), consulta la sezione Computed variables nella documentazione di ogni stat: ?stat_bin, ?stat_count, ?stat_smooth, etc.

Layer 6: Coordinates

Il “tessuto” su cui plottiamo - operano dopo scale:

Tipi principali:

  • coord_cartesian() - Default (x, y piano)
  • coord_flip() - Scambia x ↔︎ y
  • coord_fixed() - Ratio fisso (utile per mappe)
  • coord_polar() - Coordinate polari (pie chart)
  • coord_map() - Proiezioni geografiche
  • coord_trans() - Trasformazioni non-lineari

Zoom senza rimuovere dati:

coord_cartesian(xlim = c(2, 5),
                ylim = c(10, 30))

Scales: Il Traduttore Bidirezionale

Le scale traducono BIDIREZIONALMENTE tra dati e proprietà visive

Il problema fondamentale:

I tuoi dati raramente rappresentano direttamente proprietà grafiche:

  • gender → quale forma?
  • temperature (15-35°C) → quale colore?
  • date (2020-01-01) → quale posizione?
  • category (A, B, C) → quale colore?

Ogni aesthetics ha la sua scala:

ggplot(data, aes(x = date, 
                 y = temp,
                 color = city)) +
  geom_line()
  
# ggplot2 applica AUTOMATICAMENTE:
# scale_x_date()       # per x
# scale_y_continuous() # per y
# scale_color_discrete() # per color

Automatiche ma personalizzabili

Le scale vengono sempre applicate, anche se non le specifichi. Specificarle esplicitamente ti dà controllo totale.

Scales: Anatomia e Pattern

Pattern di nomenclatura sistematico:

scale_<aesthetic>_<type>()

Per POSIZIONI (x, y):

# Continuous
scale_x_continuous()
scale_y_continuous()

# Trasformazioni
scale_x_log10()      # scala logaritmica
scale_y_sqrt()       # radice quadrata
scale_x_reverse()    # inverte direzione

# Tipi speciali
scale_x_date()       # date/datetime
scale_x_discrete()   # categorie
scale_x_binned()     # bins per continuous

Per COLORE (color/fill):

# Continuous
scale_color_gradient(low = "blue", high = "red")
scale_color_gradient2(mid = "white")  # divergente
scale_color_viridis_c()  # perceptually uniform

# Discrete
scale_color_brewer(palette = "Set1")
scale_color_manual(values = c("red", "blue"))
scale_fill_grey()    # scala di grigi

Per ALTRE AESTHETICS:

# Size
scale_size_continuous(range = c(1, 10))
scale_size_area()  # area proporzionale al valore

# Shape
scale_shape_manual(values = c(16, 17, 18))
scale_shape_discrete()

# Alpha (trasparenza)
scale_alpha_continuous(range = c(0.1, 1))

# Linetype
scale_linetype_manual(values = c("solid", "dashed"))

Suffissi importanti:

  • _manual → valori completamente custom
  • _identity → usa valore letterale dai dati

Scales: Personalizzazione Completa

Componenti comuni a tutte le scale (tutti opzionali):

scale_color_gradient(
  name = "Temperatura (°C)",  # Titolo legenda/asse
  limits = c(0, 100),         # Range dei dati
  breaks = seq(0, 100, 25),   # Tick marks
  labels = c("0°", "25°", "50°", "75°", "100°"),
  trans = "log10",            # Trasformazione
  guide = guide_colorbar(     # Tipo di guida
    barwidth = 15,
    barheight = 0.5
  )
)

Controllo delle legende/assi:

# Rimuovi legenda per una aesthetic
scale_color_continuous(guide = "none")

# Multiple guide types
guide_legend()     # legenda discreta
guide_colorbar()   # barra continua
guide_bins()       # bins
guide_axis()       # assi personalizzati

Trasformazioni comuni:

# Coordinate vs Scale transforms
scale_x_log10()  # trasforma DATI (prima stats)
coord_trans(x = "log10")  # trasforma VISUAL

# Differenza cruciale:
ggplot(data, aes(x, y)) +
  geom_smooth() +
  scale_x_log10()  # smooth su dati log-transformed

ggplot(data, aes(x, y)) +
  geom_smooth() +
  coord_trans(x = "log10")  # smooth su dati originali

Scale types riconoscono automaticamente i dati

ggplot2 sceglie intelligentemente: - factor/character_discrete() - numeric/integer_continuous()
- Date/POSIXct_date()/_datetime()

Ma puoi sempre sovrascrivere manualmente!

Layer 7: Theme

Controllo completo su elementi non-data (tutto ciò che non rappresenta dati):

Temi built-in:

theme_gray()      # default
theme_minimal()   # minimalista
theme_classic()   # assi classici
theme_bw()        # bianco e nero
theme_dark()      # sfondo scuro
theme_void()      # vuoto (solo dati)

Pacchetti con temi extra:

  • ggthemes: Economist, FiveThirtyEight, Tufte
  • hrbrthemes: Typography-focused
  • tvthemes: Simpsons, Game of Thrones…

Layer 7: Theme

Personalizzazione con theme() - Categorie principali:

theme(
  # Testo
  plot.title = element_text(size = 16, face = "bold"),
  axis.text = element_text(size = 10),
  axis.title.x = element_text(margin = margin(t = 10)),
  
  # Linee
  axis.line = element_line(color = "black", linewidth = 0.5),
  panel.grid.major = element_line(color = "gray90"),
  panel.grid.minor = element_blank(),  # rimuovi
  
  # Rettangoli/Sfondi
  panel.background = element_rect(fill = "white"),
  plot.background = element_rect(fill = "gray95"),
  
  # Legend
  legend.position = "bottom",  # "none", "left", "right", "top"
  legend.title = element_blank()
)

Theme elements

Quattro tipi di elementi per personalizzazione completa:

1. element_text() - Testo (titoli, labels, caption):

plot.title = element_text(
  family = "Helvetica", face = "bold", size = 16, 
  color = "steelblue", hjust = 0.5, margin = margin(b = 10)
)

2. element_line() - Linee (assi, griglie):

axis.line = element_line(color = "black", linewidth = 1, linetype = "solid")
panel.grid = element_line(color = "gray90", linewidth = 0.5)

3. element_rect() - Rettangoli (sfondi, bordi):

panel.background = element_rect(fill = "white", color = "black", linewidth = 1)
legend.background = element_rect(fill = "gray95", color = NA)

4. element_blank() - Rimuove elemento:

panel.grid.minor = element_blank()  # rimuove griglia secondaria
axis.text.y = element_blank()       # rimuove etichette y

Theme elements - Gerarchia

Gerarchia degli elementi - Da generale a specifico:

theme(
  # Livello 1: Globale
  text = element_text(family = "Arial", size = 12),
  line = element_line(color = "gray30"),
  
  # Livello 2: Categoria
  axis.text = element_text(size = 10),  # eredita family da text
  
  # Livello 3: Specifico (override)
  axis.text.x = element_text(angle = 45, hjust = 1),
  axis.text.y = element_text(color = "red")
)

Tip: Modifica elementi più generali possibile per consistenza!

Salvare tema custom:

my_theme <- theme_minimal() + 
  theme(text = element_text(family = "Roboto"))

# Applica a tutti i plot della sessione
theme_set(my_theme)

Position adjustments

Modifica posizione elementi dentro un layer (risolve overlapping):

# Identity - nessun aggiustamento (dati sovrapposti)
geom_bar(position = "identity", alpha = 0.5)

# Stack - impilati (default per barre)
geom_bar(position = "stack")

# Dodge - affiancati (gruppi side-by-side)
geom_bar(position = "dodge")

# Fill - impilati a 100%
geom_bar(position = "fill")

# Jitter - rumore casuale (scatter plot con sovrapposizione)
geom_point(position = "jitter")
geom_point(position = position_jitter(width = 0.2, height = 0))

Fondamentale per visualizzare correttamente dati sovrapposti!

Layer multipli

ggplot2 è compositivo - somma layer!

ggplot(mpg, aes(x = displ, y = hwy)) +
  geom_point(aes(color = class)) +      # Layer 1
  geom_smooth(color = "black") +         # Layer 2
  geom_rug(sides = "bl")                 # Layer 3

Ogni layer può avere:
- Proprie estetiche
- Propri dati
- Proprie geometrie

Logica > Memorizzazione

Non memorizzare ogni funzione!

Capisci la logica:

  • Cambiare aspetto dati? → geoms
  • Cambiare colori/scale? → scales
  • Cambiare elementi non-data? → theme
  • Dividere in sottografici? → facets

Il sistema è consistente e prevedibile

Componibilità

I componenti sono progettati per lavorare insieme:

  • Stessi principi per tutti i tipi di grafici
  • Esplorazione sistematica
  • Creazione di visualizzazioni originali
  • Riduce carico cognitivo

La grammatica rende ggplot2 intuitivo una volta capito il sistema!

Vantaggi del framework

  1. Consistenza: Stesso approccio per tutti i grafici
  2. Flessibilità: Mix & match componenti
  3. Espandibilità: Facile creare nuove geometrie
  4. Leggibilità: Codice dichiarativo e chiaro
  5. Riproducibilità: Tutto nel codice, no click
  6. Potenza: Da semplici a complessi con stessa logica

Ecosistema di estensioni

ggplot2 è una piattaforma, non solo un package!

200+ estensioni disponibili:

  • patchwork - Composizione grafici
  • gganimate - Animazioni
  • ggrepel - Etichette intelligenti
  • ggraph - Network/grafi
  • ggridges - Ridge plots
  • … molte altre!

Gallery completa

Recap: I 7 layer

  1. Data - Dataset (data = mpg)
  2. Aesthetics - Mappature (aes(x, y, color))
  3. Geometries - Forme visive (geom_point())
  4. Stats - Trasformazioni (stat_bin())
  5. Scales - Controllo mappature (scale_color_*())
  6. Coordinate - Sistema coordinate (coord_flip())
  7. Facets - Sottografici (facet_wrap())

+ Theme per aspetto generale!

Risorse

Libri:

Online:

Video: Thomas Lin Pedersen’s workshop (4.5h)