Che cosa accade eseguendo l'istruzione seguente?
ggplot(utenti, aes(x = eta, y = anno_iscrizione)) |>
geom_point()
In ggplot2 un grafico si costruisce sommando dei
layer con l'operatore +: ggplot()
definisce i dati e le corrispondenze estetiche,
geom_point() aggiunge lo strato dei punti. Con la pipe, il
risultato di ggplot() verrebbe passato come primo argomento
di geom_point(), che invece si aspetta una corrispondenza
estetica: R restituisce un errore, e ggplot2 suggerisce
esplicitamente di usare + al posto della pipe.
La seconda opzione è il risultato che si otterrebbe con
+. La terza è la più insidiosa: un grafico con i soli assi
è quello che si ottiene eseguendo ggplot(...) senza alcun
layer geometrico, ma qui la chiamata a geom_point() produce
un errore. La quarta è priva di fondamento.
Che differenza c'è tra i due grafici seguenti?
ggplot(utenti, aes(x = eta, y = anno_iscrizione)) +
geom_point(aes(color = "blue"))
ggplot(utenti, aes(x = eta, y = anno_iscrizione)) +
geom_point(color = "blue")
All'interno di aes() si indicano le
corrispondenze tra le variabili dei dati e le
caratteristiche estetiche del grafico (mapping). Scrivendo
aes(color = "blue"), ggplot2 tratta
"blue" come il valore di una variabile costante: le assegna
il primo colore della sua tavolozza e crea una legenda. Per fissare un
colore uguale per tutti i punti (setting) bisogna indicarlo
fuori da aes(), come argomento del layer.
La seconda e la quarta opzione sono le più insidiose: il codice sembra chiedere i punti blu in entrambi i casi, ma solo il secondo grafico li disegna davvero di quel colore. La terza inverte la regola.
La tibble freq contiene la distribuzione degli utenti
per categoria, con le colonne categoria e n
(frequenze assolute). Quale istruzione produce il diagramma a barre
corretto?
geom_col disegna barre la cui altezza è indicata da una
variabile dei dati (qui n): è adatto quando le frequenze
sono già state calcolate. geom_bar, invece,
calcola le frequenze contando le righe della tabella
per ciascuna modalità di x: si usa sui dati originari, ad
esempio
ggplot(utenti, aes(x = categoria)) + geom_bar().
La seconda opzione è la più insidiosa: applicata a freq,
geom_bar conta le righe, una per categoria, e disegna barre
tutte alte 1. La terza restituisce un errore, perché
geom_bar non accetta un'estetica y (a meno di
indicare stat = "identity", cioè di fare ciò che fa
geom_col). La quarta rappresenta la distribuzione delle
frequenze, non quella delle categorie.
Che cosa rappresenta il seguente grafico?
ggplot(prestiti_completo, aes(x = categoria, fill = genere_letterario)) +
geom_bar(position = "fill")
Con position = "fill" le barre impilate vengono
riscalate in modo da avere tutte altezza 1: ogni barra mostra la
composizione percentuale della propria modalità di x (la
categoria) secondo la variabile di fill (il genere
letterario). È l'equivalente grafico di
adorn_percentages("row") sulla tabella con la categoria in
riga.
La seconda opzione descrive la posizione di default,
position = "stack". La terza descrive
position = "dodge". La quarta è la più insidiosa: descrive
il grafico che si otterrebbe scambiando le variabili assegnate a
x e a fill.
Che cosa fa il layer facet_wrap(vars(categoria))
aggiunto a un istogramma dell'età?
Le funzioni facet_wrap e facet_grid
suddividono il grafico in più pannelli (facet), uno per
ciascuna modalità della variabile indicata all'interno di
vars(). Ogni pannello rappresenta il sottoinsieme dei dati
della propria modalità, e per default tutti i pannelli condividono le
stesse scale, il che facilita il confronto.
La seconda opzione è la più insidiosa: descrive l'effetto di
aes(fill = categoria), che sovrappone i gruppi in un unico
pannello. La terza e la quarta attribuiscono a facet_wrap
funzioni che non ha.
Nel grafico seguente i punti e i boxplot rappresentano gli stessi dati:
ggplot(utenti, aes(x = categoria, y = eta)) +
geom_jitter(width = 0.2) +
geom_boxplot()
Che cosa si osserva?
In ggplot2 i layer si sovrappongono come fogli
trasparenti, nell'ordine in cui vengono aggiunti con +:
ogni layer viene disegnato sopra i precedenti. Qui i boxplot, aggiunti
per ultimi, coprono i punti. Per vedere i punti sopra i boxplot si
invertono i due layer, oppure si rende il boxplot trasparente (ad
esempio con alpha = 0.5).
La seconda opzione è la più insidiosa: è l'impressione che si ha guardando molti grafici, in cui i punti sono stati aggiunti per ultimi. La terza è errata: l'ordine dei layer non produce errori. La quarta è errata: tutti i layer vengono disegnati.
Eseguendo
ggplot(utenti, aes(x = eta)) + geom_histogram(), R stampa
il messaggio
`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Che cosa significa?
Il messaggio non è un errore: il grafico viene disegnato, ma con un numero di classi (30) fissato per default. Il numero e l'ampiezza delle classi influenzano molto la forma dell'istogramma, e la scelta va fatta guardando i dati e la loro unità di misura: per l'età, ad esempio, sono naturali classi di 5 o 10 anni.
La seconda opzione è la più insidiosa: confonde un messaggio informativo con un errore. La terza e la quarta attribuiscono al numero 30 un significato che non ha.
Nella grammatica dei grafici di ggplot2, che cosa
stabilisce lo strato delle estetiche, definito con
aes()?
Le estetiche (aesthetics) descrivono la corrispondenza tra
le variabili dei dati e le caratteristiche visive del grafico: ad
esempio
aes(x = eta, y = anno_iscrizione, color = categoria)
associa l'età all'asse orizzontale, l'anno di iscrizione a quello
verticale e la categoria al colore. Per ogni estetica
ggplot2 costruisce una scala e, quando serve, una
legenda.
La seconda opzione descrive lo strato del tema
(theme_*() e theme()), la terza quello delle
geometrie (geom_*()). La quarta è la più insidiosa, perché
titolo ed etichette degli assi riportano per default i nomi delle
variabili indicate in aes(); si modificano però con
labs().
Che differenza c'è tra aggiungere a un diagramma di dispersione con
una curva di regressione (geom_smooth()) il layer
coord_cartesian(xlim = c(0, 40000)) e il layer
scale_x_continuous(limits = c(0, 40000))?
Lo strato delle coordinate stabilisce lo spazio in cui i dati vengono
disegnati: coord_cartesian(xlim = ...) funziona come uno
zoom, e tutti i calcoli (ad esempio la curva di
geom_smooth()) usano tutti i dati. I limiti di una scala,
invece, agiscono sui dati prima dei calcoli: i valori fuori
dall'intervallo diventano mancanti e vengono esclusi (R lo segnala con
un avvertimento), quindi la curva può cambiare.
La seconda opzione è la più insidiosa: la parte di grafico visibile è
la stessa, ma i calcoli no. La terza inverte i due comportamenti. La
quarta confonde coord_cartesian con
coord_polar.
Dove compare la legenda nel grafico seguente?
ggplot(utenti, aes(x = eta, y = anno_iscrizione, color = categoria)) +
geom_point() +
theme(legend.position = "bottom") +
theme_minimal()
I temi completi (theme_minimal(),
theme_bw(), theme_classic(), ...) impostano
tutti gli elementi non legati ai dati; la funzione
theme() ne modifica invece solo alcuni. Come per gli altri
layer, conta l'ordine: un tema completo aggiunto dopo
theme() ne annulla le modifiche. Per spostare la legenda in
basso bisogna scrivere prima theme_minimal() e poi
theme(legend.position = "bottom").
La seconda opzione è la più insidiosa, perché sarebbe vera invertendo
l'ordine dei due layer. La terza attribuisce a
theme_minimal() un effetto che non ha. La quarta è errata:
l'ordine sbagliato non produce errori, e proprio per questo il risultato
va controllato.
Dopo aver disegnato un grafico ggplot2, si esegue
l'istruzione ggsave("grafico.png", width = 7, height = 4).
Che cosa succede?
Se l'argomento plot non viene indicato,
ggsave salva l'ultimo grafico ggplot2
mostrato. Le dimensioni sono espresse per default in pollici
(inches); si possono usare altre unità con l'argomento
units, ad esempio units = "cm". Il formato del
file viene ricavato dall'estensione del nome (.png,
.pdf, .jpg, ...).
La terza opzione è la più insidiosa: indicare esplicitamente il
grafico (ggsave("grafico.png", g, ...)) è una buona
abitudine, ma non è obbligatorio. La seconda e la quarta sbagliano
l'unità di misura di default.
Che effetto ha il layer scale_x_log10() su un diagramma
di dispersione del PIL pro capite (asse x) e dell'aspettativa di vita
(asse y)?
Le scale stabiliscono come i valori delle variabili diventano
posizioni, colori o dimensioni. Con scale_x_log10() le
posizioni sull'asse orizzontale sono proporzionali al logaritmo dei
valori: le variabili molto asimmetriche, come il reddito, vengono
"aperte" e le relazioni moltiplicative diventano lineari. I dati non
vengono modificati e le etichette dell'asse mostrano i valori
originali.
La prima e la terza opzione distrattrici confondono la scala con una
trasformazione dei dati, che si otterrebbe ad esempio con
aes(x = log10(gdp_per_cap)): in quel caso sull'asse
comparirebbero i logaritmi. La quarta è priva di fondamento.
Che grafico produce il codice seguente?
ggplot(utenti, aes(x = eta)) +
geom_histogram(binwidth = 10) +
facet_grid(rows = vars(genere), cols = vars(categoria))
facet_grid() dispone i pannelli in una griglia: la
variabile indicata in rows definisce le righe, quella
indicata in cols le colonne. Qui si ottengono 2 righe
(Femmina, Maschio) e 5 colonne (le categorie).
facet_wrap(vars(variabile)), invece, usa una sola variabile
e "avvolge" i pannelli su più righe per riempire lo spazio.
La seconda opzione è la più insidiosa, perché inverte righe e
colonne. La terza descrive piuttosto
facet_wrap(vars(genere, categoria), nrow = 1). La quarta
descrive l'effetto di un'estetica di riempimento, non dei facet.
La tabella prestiti_mese_bib contiene il numero di
prestiti n per ciascuna biblioteca (B01, B02,
B03, B04) e mese (da 1 a 12). Che cosa disegna il codice
seguente?
ggplot(prestiti_mese_bib, aes(x = mese, y = n)) +
geom_line()
geom_line() collega i punti in ordine di x
all'interno di ciascun gruppo. I gruppi sono definiti dalle variabili
qualitative associate a un'estetica (ad esempio
color = biblioteca) oppure esplicitamente con
group = biblioteca. Qui non c'è nessuna estetica di questo
tipo: le 48 righe formano un unico gruppo, e la linea passa per tutti i
punti, con tratti verticali in corrispondenza di ciascun mese.
La seconda opzione si otterrebbe con
aes(group = biblioteca), la terza con
aes(color = biblioteca). La quarta è la più insidiosa:
geom_line() non calcola medie, rappresenta i valori così
come sono nella tabella.
Che cosa si trova nel portale ggplot2 extensions (exts.ggplot2.tidyverse.org)?
Grazie alla sua struttura a layer, ggplot2 può essere
esteso da altri package che aggiungono nuovi layer, temi, scale o modi
di combinare i grafici: ad esempio ggridges (curve di
densità sovrapposte), ggrepel (etichette che non si
sovrappongono), patchwork (composizione di più grafici),
gganimate (animazioni). Il portale ne raccoglie un'ampia
selezione, con un'immagine di esempio e il link alla documentazione di
ciascuno.
La quarta opzione è la più insidiosa: le estensioni sono package a sé
stanti, che vanno installati con install.packages() e
caricati con library(). La seconda confonde il portale con
la documentazione di ggplot2, la terza con gli strumenti di
intelligenza artificiale.
Dopo aver caricato il package patchwork, che cosa
produce l'istruzione g1 / g2, dove g1 e
g2 sono due grafici ggplot2?
Il package patchwork ridefinisce alcuni operatori
aritmetici per comporre più grafici in un'unica figura:
g1 + g2 (o g1 | g2) li affianca,
g1 / g2 li mette uno sopra l'altro, e le parentesi
permettono composizioni più complesse, come (g1 | g2) / g3.
Il layer plot_annotation() aggiunge un titolo complessivo e
le lettere che identificano i singoli grafici.
La seconda opzione è la più insidiosa, perché descrive l'operatore
+ (o |). La terza confonde la composizione di
grafici con l'aggiunta di layer a un unico grafico. La quarta ignora che
patchwork ridefinisce l'operatore / per i
grafici.
Che cosa fa la funzione ggplotly() del package
plotly, applicata a un grafico ggplot2 salvato
nell'oggetto g?
plotly è una libreria JavaScript per la grafica
interattiva, accessibile da R con l'omonimo package. Il modo più
semplice per usarla è costruire il grafico con ggplot2 e
trasformarlo con ggplotly(g), senza imparare una nuova
sintassi. Il risultato è un htmlwidget, che si visualizza nel
pannello Viewer o nel browser e si salva in un file html.
La terza opzione è la più insidiosa: la conversione avviene
direttamente, senza dover riscrivere il grafico. La seconda descrive
piuttosto ggsave(). La quarta è errata:
ggplotly() lavora proprio sui grafici
ggplot2.
Il grafico g è stato costruito con ggplot2
usando il layer
geom_point_interactive(aes(tooltip = id_utente)) del
package ggiraph. Che cosa si ottiene stampando
semplicemente g?
ggiraph fornisce le versioni interattive delle geometrie
di ggplot2 (geom_point_interactive,
geom_col_interactive, geom_jitter_interactive,
...), con nuove estetiche come tooltip e
data_id. Il grafico si costruisce come un normale grafico
ggplot2, e stampato da solo resta statico: diventa
interattivo solo quando viene passato alla funzione
girafe(), che lo trasforma in un htmlwidget.
La seconda opzione è la più insidiosa, perché descrive il risultato
di girafe(ggobj = g). La terza è errata: i layer
interattivi sono pensati proprio per essere sommati agli altri layer di
ggplot2. La quarta descrive l'effetto di
geom_text().
In un grafico ggiraph dei singoli utenti, i punti sono
disegnati con
geom_jitter_interactive(aes(tooltip = id_utente, data_id = categoria)).
Che cosa succede passando il mouse su un punto?
In ggiraph l'estetica tooltip stabilisce il
testo dell'etichetta che compare passando il mouse su un elemento,
mentre data_id identifica gli elementi da evidenziare
insieme: tutti gli elementi con lo stesso valore di data_id
vengono evidenziati contemporaneamente. Con
data_id = categoria, passando il mouse su uno studente si
evidenziano tutti gli studenti; con data_id = id_utente si
evidenzierebbe solo il punto corrente. L'aspetto degli elementi
evidenziati si modifica con le opzioni di girafe(), ad
esempio opts_hover().
La seconda opzione è la più insidiosa, perché scambia i ruoli delle
due estetiche. La terza e la quarta attribuiscono a data_id
effetti che non ha.
Nell'istruzione
hchart(prestiti_cat_genere, "column", hcaes(x = categoria, y = n, group = genere_letterario))
del package highcharter, qual è il ruolo di
hcaes()?
highcharter dà accesso da R alla libreria JavaScript
Highcharts. La funzione hchart() riceve la tabella dei
dati, il tipo di grafico ("column", "bar",
"line", "scatter", ...) e le corrispondenze
tra variabili ed elementi del grafico, indicate con
hcaes(), l'analogo di aes();
group crea una serie per ciascuna modalità. Il grafico si
modifica poi con le funzioni hc_*() concatenate con la
pipe, ad esempio hc_title() o
hc_plotOptions().
La terza opzione è la più insidiosa: hchart() con il
tipo "column" rappresenta valori già calcolati (come
geom_col), e le frequenze vanno calcolate prima, ad esempio
con count(). La seconda descrive
hc_add_theme(), la quarta piuttosto
ggplotly().
Per rappresentare con dygraph() l'andamento mensile dei
prestiti delle quattro biblioteche, in quale forma devono essere
organizzati i dati?
dygraphs è pensato per le serie storiche: rappresenta
una o più serie, una per colonna, rispetto a un indice temporale. I dati
vanno quindi portati in formato largo (ad esempio con
pivot_wider(), una colonna per biblioteca) e trasformati in
un oggetto xts con
xts(colonne, order.by = date). Al grafico si aggiungono poi
altre funzionalità con le funzioni dy*(), ad esempio
dyRangeSelector() per scegliere l'intervallo temporale da
visualizzare.
La seconda opzione è la più insidiosa: è il formato tidy
richiesto da ggplot2, non quello richiesto da
dygraph(). La terza confonde dygraphs con
plotly. La quarta perde l'informazione sulle date e sulle
biblioteche.
Come si salva in un file un grafico interattivo costruito con
plotly, ggiraph, highcharter o
dygraphs?
I quattro package producono htmlwidgets: grafici costruiti
in R ma disegnati da librerie JavaScript, che funzionano in una pagina
web. Per questo si salvano in file html con
htmlwidgets::saveWidget(grafico, "file.html"), e si possono
inserire in un documento Quarto in formato html o in un sito.
La seconda opzione è la più insidiosa: ggsave() salva i
grafici ggplot2 in formati statici, nei quali
l'interattività non può esistere. La terza riguarda le animazioni di
gganimate. La quarta è errata, come mostra la prima
opzione.
Qual è la differenza principale tra
transition_time(year) e
transition_states(year) in un grafico animato con
gganimate?
Entrambe le funzioni mostrano i dati un "momento" alla volta,
interpolando le posizioni nei fotogrammi intermedi.
transition_states() è pensata per variabili qualitative (o
numeriche con pochi valori): gli argomenti
transition_length e state_length regolano la
durata dei passaggi e delle pause, e nel titolo si usa
{closest_state}. transition_time() è pensata
per una variabile temporale: non ci sono pause e nel titolo si usa
{frame_time}.
La seconda opzione è la più insidiosa, perché per anni equidistanti e senza pause le due animazioni si assomigliano molto. La terza e la quarta attribuiscono alle due funzioni limiti e comportamenti che non hanno.
In un'animazione costruita con transition_time(year) sui
dati gapminder (anni dal 1952 al 2007, ogni 5 anni), il
titolo labs(title = "Anno: {frame_time}") mostra valori
come Anno: 1953.27. Perché?
Per default l'animazione ha 100 fotogrammi, mentre gli anni sono 12:
gganimate calcola le posizioni nei fotogrammi intermedi
interpolando tra un anno e l'altro, e {frame_time} riporta
il tempo di ciascun fotogramma, che quasi sempre cade tra due anni. Tra
le parentesi graffe si può scrivere un'espressione R, ad esempio
{round(frame_time)}.
La terza opzione è la più insidiosa: aumentando il numero di
fotogrammi i fotogrammi intermedi diventano ancora di più. La seconda è
errata, perché year contiene numeri interi. La quarta
confonde il tempo dei dati con la durata dell'animazione.
In un'animazione con transition_states(continent) i
paesi di un continente vengono mostrati uno stato alla volta. Senza
indicazioni particolari, nel passaggio da un continente all'altro i
punti si spostano e cambiano colore, come se un paese africano
"diventasse" un paese americano. Come si evita questo effetto?
Per costruire i fotogrammi intermedi gganimate abbina le
righe di uno stato a quelle dello stato successivo e le sposta
gradualmente. L'abbinamento si basa sui gruppi: indicando
group = country, ogni paese è un oggetto distinto e, poiché
compare in un solo stato, non viene abbinato a nessun altro. Gli oggetti
senza corrispondenti entrano ed escono dall'animazione:
enter_fade(), enter_grow(),
exit_shrink(), ... stabiliscono il modo.
La seconda opzione è la più insidiosa: ease_aes() cambia
l'andatura del movimento, non gli oggetti che si muovono. La terza
aggiunge una traccia degli stati passati, ma non cambia gli abbinamenti.
La quarta è errata.
Quanto dura l'animazione prodotta da
animate(p, nframes = 100, fps = 20)?
In animate() l'argomento nframes stabilisce
il numero di fotogrammi e fps (frames per second)
quanti fotogrammi vengono mostrati ogni secondo: la durata è quindi
nframes / fps = 100 / 20 = 5 secondi. In alternativa a
fps si può indicare direttamente la durata con l'argomento
duration. Più fotogrammi rendono l'animazione più fluida,
ma richiedono più tempo di calcolo.
La seconda opzione confonde la durata con il numero di fotogrammi al secondo, la terza con il numero di fotogrammi, la quarta moltiplica invece di dividere.
Che cosa mostra, in ciascun fotogramma, l'animazione seguente?
ggplot(prestiti_mese_bib, aes(x = mese, y = n, color = biblioteca)) +
geom_line() +
geom_point() +
transition_reveal(mese)
transition_reveal() "scopre" i dati progressivamente
lungo la variabile indicata, ed è l'animazione naturale per un grafico a
linee: la linea mostra il percorso compiuto fino al momento corrente. I
punti, invece, rappresentano singole osservazioni: in ogni fotogramma
viene mostrato solo quello del momento corrente. Per lasciare visibili
anche i punti precedenti si può aggiungere
shadow_mark().
La seconda opzione è la più insidiosa, perché descrive il risultato
che si otterrebbe aggiungendo shadow_mark(). La terza
ignora geom_line(). La quarta descrive un grafico in cui le
linee sono già interamente visibili, mentre
transition_reveal() le disegna progressivamente.