ggplot2 - Grafici Avanzati in R
ggplot2 eā LA libreria di visualizzazione di R e uno dei pacchetti piuā influenti dellāintero ecosistema. Creata da Hadley Wickham, ggplot2 si basa sulla āGrammatica dei Graficiā (Grammar of Graphics) di Leland Wilkinson, un framework teorico che permette di costruire qualsiasi grafico combinando componenti indipendenti. Ogni grafico in ggplot2 eā composto da dati, mappature estetiche e geometrie, rendendo il sistema estremamente flessibile e coerente.
Installazione e Caricamento
# Installazione del pacchetto
install.packages("ggplot2")
# Caricamento
library(ggplot2)
# Oppure caricare l'intero tidyverse
library(tidyverse)
La Grammatica dei Grafici
In ggplot2, ogni grafico eā costruito combinando diversi componenti (layer):
- Data: il dataset da visualizzare
- Aesthetics (aes): le mappature tra variabili e proprietaā visive (posizione, colore, forma, dimensione)
- Geometries (geom): il tipo di rappresentazione grafica (punti, linee, barre, ecc.)
- Facets: la suddivisione in sotto-grafici
- Statistics: trasformazioni statistiche dei dati
- Coordinates: il sistema di coordinate
- Themes: lāaspetto estetico complessivo del grafico
La sintassi segue sempre lo stesso schema: ggplot(data, aes(...)) + geom_*().
# Struttura base di un grafico ggplot2
ggplot(data = mtcars, aes(x = wt, y = mpg)) +
geom_point()
geom_point() - Scatter Plot
Lo scatter plot eā il grafico piuā comune per esplorare relazioni tra due variabili numeriche.
# Scatter plot base
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point()
# Scatter plot con colore per variabile categorica
ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl))) +
geom_point(size = 3) +
labs(
title = "Relazione tra Peso e Consumo",
subtitle = "Dataset mtcars - 32 automobili",
x = "Peso (1000 lbs)",
y = "Miglia per Gallone",
color = "Cilindri"
)
# Scatter plot con dimensione e forma
ggplot(mtcars, aes(x = wt, y = mpg,
color = factor(cyl),
size = hp,
shape = factor(am))) +
geom_point(alpha = 0.7) +
labs(
title = "Analisi Multidimensionale delle Auto",
x = "Peso (1000 lbs)",
y = "MPG",
color = "Cilindri",
size = "Cavalli",
shape = "Cambio"
) +
scale_shape_manual(values = c(16, 17),
labels = c("Automatico", "Manuale"))
# Aggiungere una linea di tendenza
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point(color = "steelblue", size = 2) +
geom_smooth(method = "lm", color = "red", se = TRUE) +
labs(title = "Regressione Lineare Peso-Consumo",
x = "Peso", y = "MPG")
geom_line() - Grafici a Linee
geom_line() eā ideale per dati temporali o serie ordinate.
# Creare dati temporali
set.seed(42)
dati_mensili <- data.frame(
mese = rep(1:12, 2),
anno = rep(c("2024", "2025"), each = 12),
vendite = c(
round(cumsum(rnorm(12, 5, 2)) + 100),
round(cumsum(rnorm(12, 7, 2)) + 110)
)
)
# Grafico a linee con colori per anno
ggplot(dati_mensili, aes(x = mese, y = vendite, color = anno)) +
geom_line(linewidth = 1.2) +
geom_point(size = 2) +
scale_x_continuous(breaks = 1:12, labels = month.abb) +
labs(
title = "Andamento Vendite Mensili",
x = "Mese",
y = "Vendite (migliaia EUR)",
color = "Anno"
) +
theme_minimal()
geom_bar() e geom_col() - Grafici a Barre
geom_bar() conta automaticamente le occorrenze, mentre geom_col() usa valori forniti direttamente.
# geom_bar() - conta automaticamente
ggplot(mtcars, aes(x = factor(cyl), fill = factor(cyl))) +
geom_bar() +
labs(
title = "Numero di Auto per Cilindri",
x = "Cilindri",
y = "Conteggio",
fill = "Cilindri"
) +
scale_fill_manual(values = c("steelblue", "darkorange", "darkred")) +
theme_minimal()
# Barre raggruppate
ggplot(mtcars, aes(x = factor(cyl), fill = factor(am))) +
geom_bar(position = "dodge") +
scale_fill_manual(values = c("steelblue", "coral"),
labels = c("Automatico", "Manuale")) +
labs(
title = "Cilindri per Tipo di Cambio",
x = "Cilindri",
y = "Conteggio",
fill = "Cambio"
) +
theme_minimal()
# Barre impilate con percentuali
ggplot(mtcars, aes(x = factor(cyl), fill = factor(am))) +
geom_bar(position = "fill") +
scale_y_continuous(labels = scales::percent) +
scale_fill_manual(values = c("steelblue", "coral"),
labels = c("Automatico", "Manuale")) +
labs(
title = "Distribuzione Percentuale Cambio per Cilindri",
x = "Cilindri",
y = "Percentuale",
fill = "Cambio"
) +
theme_minimal()
# geom_col() con valori diretti
dati_barre <- data.frame(
categoria = c("Prodotto A", "Prodotto B", "Prodotto C", "Prodotto D"),
valore = c(45, 72, 38, 61)
)
ggplot(dati_barre, aes(x = reorder(categoria, valore), y = valore,
fill = categoria)) +
geom_col() +
coord_flip() +
labs(title = "Vendite per Prodotto", x = "", y = "Vendite") +
theme_minimal() +
theme(legend.position = "none")
geom_histogram() - Istogrammi
geom_histogram() visualizza la distribuzione di una variabile continua.
# Istogramma base
ggplot(mtcars, aes(x = mpg)) +
geom_histogram(binwidth = 2, fill = "steelblue",
color = "white", alpha = 0.8) +
labs(
title = "Distribuzione del Consumo",
x = "Miglia per Gallone",
y = "Frequenza"
) +
theme_minimal()
# Istogramma con curva di densita' sovrapposta
ggplot(mtcars, aes(x = mpg)) +
geom_histogram(aes(y = after_stat(density)),
binwidth = 2, fill = "lightblue",
color = "darkblue", alpha = 0.7) +
geom_density(color = "red", linewidth = 1.2) +
geom_vline(aes(xintercept = mean(mpg)),
color = "darkgreen", linetype = "dashed", linewidth = 1) +
labs(
title = "Distribuzione con Densita' e Media",
x = "MPG",
y = "Densita'"
) +
theme_minimal()
# Istogrammi sovrapposti per confronto
ggplot(iris, aes(x = Sepal.Length, fill = Species)) +
geom_histogram(binwidth = 0.3, alpha = 0.6, position = "identity") +
labs(
title = "Distribuzione Lunghezza Sepalo per Specie",
x = "Lunghezza Sepalo (cm)",
y = "Frequenza",
fill = "Specie"
) +
scale_fill_brewer(palette = "Set1") +
theme_minimal()
geom_boxplot() - Diagrammi a Scatola
geom_boxplot() confronta distribuzioni tra gruppi, evidenziando mediana, quartili e outlier.
# Boxplot per gruppi
ggplot(mtcars, aes(x = factor(cyl), y = mpg, fill = factor(cyl))) +
geom_boxplot(alpha = 0.7, outlier.color = "red", outlier.size = 3) +
labs(
title = "Consumo per Numero di Cilindri",
x = "Cilindri",
y = "Miglia per Gallone",
fill = "Cilindri"
) +
scale_fill_brewer(palette = "Set2") +
theme_minimal()
# Boxplot con punti sovrapposti (jitter)
ggplot(iris, aes(x = Species, y = Petal.Length, fill = Species)) +
geom_boxplot(alpha = 0.5) +
geom_jitter(width = 0.2, alpha = 0.5, size = 1.5) +
labs(
title = "Lunghezza Petalo per Specie di Iris",
x = "Specie",
y = "Lunghezza Petalo (cm)"
) +
theme_minimal() +
theme(legend.position = "none")
# Violin plot come alternativa
ggplot(iris, aes(x = Species, y = Sepal.Width, fill = Species)) +
geom_violin(alpha = 0.6) +
geom_boxplot(width = 0.1, fill = "white", alpha = 0.8) +
labs(
title = "Distribuzione Larghezza Sepalo",
x = "Specie",
y = "Larghezza Sepalo (cm)"
) +
scale_fill_brewer(palette = "Pastel1") +
theme_minimal()
facet_wrap() e facet_grid() - Sotto-Grafici
Le facet permettono di suddividere il grafico in pannelli basati su variabili categoriche.
# facet_wrap: pannelli per una variabile
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point(color = "steelblue", size = 2) +
geom_smooth(method = "lm", color = "red", se = FALSE) +
facet_wrap(~ cyl, labeller = labeller(cyl = c(
"4" = "4 Cilindri", "6" = "6 Cilindri", "8" = "8 Cilindri"
))) +
labs(
title = "Peso vs Consumo per Numero di Cilindri",
x = "Peso (1000 lbs)",
y = "MPG"
) +
theme_minimal()
# facet_grid: griglia per due variabili
ggplot(mtcars, aes(x = hp, y = mpg, color = factor(cyl))) +
geom_point(size = 2) +
facet_grid(am ~ gear,
labeller = labeller(
am = c("0" = "Automatico", "1" = "Manuale"),
gear = c("3" = "3 Marce", "4" = "4 Marce", "5" = "5 Marce")
)) +
labs(
title = "Potenza vs Consumo per Cambio e Marce",
x = "Cavalli (HP)",
y = "MPG",
color = "Cilindri"
) +
theme_bw()
# facet_wrap con scale libere
ggplot(iris, aes(x = Sepal.Length, y = Petal.Length)) +
geom_point(aes(color = Species), size = 2, alpha = 0.7) +
facet_wrap(~ Species, scales = "free") +
labs(
title = "Relazione Sepalo-Petalo per Specie",
x = "Lunghezza Sepalo",
y = "Lunghezza Petalo"
) +
theme_minimal() +
theme(legend.position = "none")
labs() - Etichette e Titoli
labs() controlla tutti i testi del grafico: titolo, sottotitolo, didascalia e etichette degli assi.
ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl))) +
geom_point(size = 3) +
labs(
title = "Analisi del Consumo delle Automobili",
subtitle = "Relazione tra peso e consumo di carburante",
caption = "Fonte: dataset mtcars (1974 Motor Trend US)",
x = "Peso del Veicolo (migliaia di libbre)",
y = "Consumo (miglia per gallone)",
color = "Numero\nCilindri",
tag = "Fig. 1"
)
theme() - Personalizzare lāAspetto
theme() permette di controllare ogni aspetto visivo del grafico che non riguarda i dati.
# Temi predefiniti
p <- ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl))) +
geom_point(size = 3) +
labs(title = "Peso vs Consumo", x = "Peso", y = "MPG", color = "Cilindri")
# Tema minimale
p + theme_minimal()
# Tema classico
p + theme_classic()
# Tema scuro
p + theme_dark()
# Tema bianco e nero
p + theme_bw()
# Personalizzazione avanzata del tema
ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl))) +
geom_point(size = 3) +
labs(title = "Grafico Personalizzato", x = "Peso", y = "MPG",
color = "Cilindri") +
theme_minimal() +
theme(
plot.title = element_text(size = 16, face = "bold", hjust = 0.5),
axis.title = element_text(size = 12, face = "italic"),
axis.text = element_text(size = 10),
legend.position = "bottom",
legend.title = element_text(face = "bold"),
panel.grid.minor = element_blank(),
panel.border = element_rect(color = "gray50", fill = NA)
)
scale_* - Personalizzare le Scale
Le funzioni scale_* controllano la mappatura tra dati e proprietaā estetiche.
# Colori personalizzati
ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl))) +
geom_point(size = 3) +
scale_color_manual(
values = c("4" = "#2196F3", "6" = "#FF9800", "8" = "#F44336"),
labels = c("4 cilindri", "6 cilindri", "8 cilindri")
) +
labs(title = "Colori Personalizzati", color = "Motore") +
theme_minimal()
# Palette di colori predefinite
ggplot(iris, aes(x = Sepal.Length, y = Petal.Length, color = Species)) +
geom_point(size = 2) +
scale_color_brewer(palette = "Dark2") +
theme_minimal()
# Scala colore continua con gradiente
ggplot(mtcars, aes(x = wt, y = mpg, color = hp)) +
geom_point(size = 3) +
scale_color_gradient(low = "yellow", high = "red") +
labs(title = "Gradiente di Colore per Potenza",
color = "Cavalli (HP)") +
theme_minimal()
# Personalizzare gli assi
ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point(color = "steelblue", size = 2) +
scale_x_continuous(breaks = seq(1, 6, 0.5),
limits = c(1, 6)) +
scale_y_continuous(breaks = seq(10, 35, 5),
limits = c(10, 35)) +
theme_minimal()
ggsave() - Salvare i Grafici
ggsave() salva lāultimo grafico generato in un file con dimensioni e risoluzione specificate.
# Creare un grafico
p <- ggplot(iris, aes(x = Sepal.Length, y = Petal.Length,
color = Species)) +
geom_point(size = 2, alpha = 0.7) +
geom_smooth(method = "lm", se = FALSE) +
labs(title = "Relazione Sepalo-Petalo nel Dataset Iris",
x = "Lunghezza Sepalo (cm)",
y = "Lunghezza Petalo (cm)") +
theme_minimal()
# Salvare come PNG
ggsave("grafico_iris.png", plot = p, width = 10, height = 6, dpi = 300)
# Salvare come PDF
ggsave("grafico_iris.pdf", plot = p, width = 10, height = 6)
# Salvare come SVG (vettoriale)
ggsave("grafico_iris.svg", plot = p, width = 10, height = 6)
Esempio Completo: Analisi Visiva del Dataset Iris
Ecco un esempio che combina diverse funzionalitaā di ggplot2 per creare unāanalisi visiva completa.
library(ggplot2)
library(dplyr)
# 1. Scatter plot con regressione per specie
p1 <- ggplot(iris, aes(x = Sepal.Length, y = Petal.Length,
color = Species, shape = Species)) +
geom_point(size = 2.5, alpha = 0.7) +
geom_smooth(method = "lm", se = TRUE, alpha = 0.2) +
scale_color_brewer(palette = "Set1") +
labs(title = "Correlazione Sepalo-Petalo",
x = "Lunghezza Sepalo (cm)", y = "Lunghezza Petalo (cm)") +
theme_minimal() +
theme(legend.position = "bottom")
# 2. Boxplot comparativo
p2 <- ggplot(iris, aes(x = Species, y = Sepal.Width, fill = Species)) +
geom_boxplot(alpha = 0.6) +
geom_jitter(width = 0.15, alpha = 0.4, size = 1) +
scale_fill_brewer(palette = "Pastel1") +
labs(title = "Distribuzione Larghezza Sepalo",
x = "Specie", y = "Larghezza (cm)") +
theme_minimal() +
theme(legend.position = "none")
# 3. Istogramma con facet
p3 <- ggplot(iris, aes(x = Petal.Width, fill = Species)) +
geom_histogram(binwidth = 0.2, color = "white", alpha = 0.8) +
facet_wrap(~ Species, ncol = 1) +
scale_fill_brewer(palette = "Set2") +
labs(title = "Distribuzione Larghezza Petalo per Specie",
x = "Larghezza Petalo (cm)", y = "Frequenza") +
theme_minimal() +
theme(legend.position = "none")
# Per combinare i grafici si puo' usare il pacchetto patchwork
# install.packages("patchwork")
# library(patchwork)
# p1 / (p2 | p3)
# Oppure stamparli singolarmente
print(p1)
print(p2)
print(p3)
Conclusione
ggplot2 eā il sistema di visualizzazione piuā completo e flessibile disponibile in R. La sua architettura basata sulla grammatica dei grafici permette di costruire qualsiasi visualizzazione componendo layer indipendenti: dati con ggplot(), mappature con aes(), geometrie con geom_*(), sotto-grafici con facet_wrap() e facet_grid(), personalizzazione con labs(), theme() e scale_*(), e salvataggio con ggsave(). Padroneggiare ggplot2 significa poter trasformare qualsiasi dataset in visualizzazioni chiare, informative e di qualitaā professionale, pronte per report, presentazioni e pubblicazioni scientifiche.