Visualizzazione post con etichetta grafici a linee. Mostra tutti i post
Visualizzazione post con etichetta grafici a linee. Mostra tutti i post

venerdì 6 giugno 2025

Grafici a linee (line chart) con ggplot

Un grafico a linee (line chart) può essere realizzato, oltre che impiegando le funzioni base di R [1], anche con le funzioni del pacchetto ggplot2 come vediamo ora.

I dati qui utilizzati come esempio sono contenuti nel dataset "Indometh" incluso nella installazione base di R: per vedere gli altri dataset disponibili con questa (ma molti altri sono disponibili nei vari pacchetti aggiuntivi) e che possono essere utili per esercitarsi, digitare

data()

nella Console di R  premere ↵ Invio.

Digitando il nome 

Indometh

del dataset che ci interessa vediamo che contiene la concentrazione (conc) nel siero (espressa in μg/mL cioè in microgrammi per millilitro) del farmaco indometacina (un farmaco antinfiammatorio), misurata secondo la stessa precisa sequenza di ore (time) in sei soggetti (Subject) identificati con i numeri da 1 a 6 :

   Subject time conc
1        1 0.25 1.50
2        1 0.50 0.94
3        1 0.75 0.78
4        1 1.00 0.48
5        1 1.25 0.37
6        1 2.00 0.19
7        1 3.00 0.12
8        1 4.00 0.11
9        1 5.00 0.08
10       1 6.00 0.07
11       1 8.00 0.05
12       2 0.25 2.03
13       2 0.50 1.63
14       2 0.75 0.71
15       2 1.00 0.70
16       2 1.25 0.64
17       2 2.00 0.36
18       2 3.00 0.32
19       2 4.00 0.20
20       2 5.00 0.25
21       2 6.00 0.12
22       2 8.00 0.08
23       3 0.25 2.72
24       3 0.50 1.49
25       3 0.75 1.16
26       3 1.00 0.80
27       3 1.25 0.80
28       3 2.00 0.39
29       3 3.00 0.22
30       3 4.00 0.12
31       3 5.00 0.11
32       3 6.00 0.08
33       3 8.00 0.08
34       4 0.25 1.85
35       4 0.50 1.39
36       4 0.75 1.02
37       4 1.00 0.89
38       4 1.25 0.59
39       4 2.00 0.40
40       4 3.00 0.16
41       4 4.00 0.11
42       4 5.00 0.10
43       4 6.00 0.07
44       4 8.00 0.07
45       5 0.25 2.05
46       5 0.50 1.04
47       5 0.75 0.81
48       5 1.00 0.39
49       5 1.25 0.30
50       5 2.00 0.23
51       5 3.00 0.13
52       5 4.00 0.11
53       5 5.00 0.08
54       5 6.00 0.10
55       5 8.00 0.06
56       6 0.25 2.31
57       6 0.50 1.44
58       6 0.75 1.03
59       6 1.00 0.84
60       6 1.25 0.64
61       6 2.00 0.42
62       6 3.00 0.24
63       6 4.00 0.17
64       6 5.00 0.13
65       6 6.00 0.10
66       6 8.00 0.09

Ai sei soggetti era stata somministrata una identica quantità di indometacina, allo scopo di determinare la velocità alla quale il farmaco viene eliminato: un dato necessario  per stabilire posologia e intervalli di somministrazione.

Ora copiate e incollate nella Console di R questo script e premete ↵ Invio.

# GRAFICO A LINEE con ggplot
#
library(ggplot2) # carica il pacchetto per la grafica
#
# realizza il grafico a linee per ciascuno dei sei soggetti
#
ggplot(data=Indometh, aes(x=time, y=conc, group=Subject, color=Subject, linetype=Subject, shape=Subject)) + geom_line() + geom_point() + theme_classic()
#

Il grafico risultante


viene quindi realizzato:
→ specificando l'origine dei dati (Indometh);
→ riportando in ascisse il tempo (time) e in ordinate la concentrazione (conc); 
→ aggregando i dati per soggetto (group=Subject); 
→ impiegando per ciascun soggetto (Subjectun differente colore (color), linea (linetype) e simbolo (shape);  
→ riportando sul grafico i punti (geom_point) e le linee (geom_line) che li uniscono

Niente di più facile per produrre una versione base del grafico, anche se ovviamente è poi possibile aggiustare a piacere colori, dimensione dei simboli, spessore e tipo delle linee, legenda e quant'altro: esempi si trovano anche in altri post di questo sito [2], ma ovviamente raccomando comunque di scaricare e tenere a portata di mano il manuale di riferimento del pacchetto [3]. Da notare infine che il messaggio che si vede comparire

Messaggio di avvertimento:
Using shapes for an ordinal variable is not advised 

è semplicemente un suggerimento e può essere ignorato.

Ora, visto l'andamento simile delle sei curve di eliminazione del farmaco, l'idea è di realizzare un grafico che riporti per ciascuno dei tempi la media delle concentrazioni rilevate nei sei soggetti e i suoi limiti di confidenza al 95%, rappresentati dalla media +1.96 volte l'errore standard (es) e dalla media -1.96 volte l'errore standard. Per questo copiate e incollate nella Console di R queste righe e premete ↵ Invio.

#
library(plotrix) # carica il pacchetto per il calcolo dell'errore standard
#
# aggrega i dati per ciascun tempo e calcola media ed errore standard della concentrazione per ciascun tempo
#
mydata <- aggregate(conc~time, data=Indometh, FUN=function(x) c(mean=mean(x), se=std.error(x))) 
#
mydata # mostra i dati calcolati
#
media <- mydata$conc[,1] # salva in un vettore le medie calcolate
es <- mydata$conc[,2] # salva in un vettore gli errori standard calcolati
#

Come si vede:
→ serve il pacchetto plotrix, che deve essere preventivamente installato e che fornisce la funzione std.error() per calcolare l'errore standard della media;
→ con la funzione aggregate() sono aggregate le concentrazioni del farmaco rilevate nei sei soggetti a ciascun tempo (conc~time);
→ con FUN=function(x) sono calcolati sui sei valori di concentrazione rilevati a ciascun tempo la media mean(x) e l'errore standard std.err(x);
→ per semplificare e rendere più leggibile il codice successivo media (conc.mean) ed errore standard (conc.se) sono salvati rispettivamente nel vettore media e nel vettore es.

Questi sono i dati calcolati che troviamo in mydata

> mydata # mostra i dati calcolati
   time   conc.mean     conc.se
1  0.25 2.076666667 0.168832593
2  0.50 1.321666667 0.110616957
3  0.75 0.918333333 0.071991512
4  1.00 0.683333333 0.083373324
5  1.25 0.556666667 0.076361712
6  2.00 0.331666667 0.039616214
7  3.00 0.198333333 0.031242777
8  4.00 0.136666667 0.015846486
9  5.00 0.125000000 0.026172505
10 6.00 0.090000000 0.008164966
11 8.00 0.071666667 0.006009252

Dopo questo necessario passo intermedio possiamo di nuovo tornare alla rappresentazione del grafico a linee, copiate e incollate nella Console di R queste ultime righe di codice e premete ↵ Invio.

#
windows() # apre e inizializza una nuova finestra grafica
#
# realizza il grafico a linee riportando per ciascun tempo i limiti di confidenza al 95% della media 
#
ggplot(data=mydata, aes(x=time, y=media)) + geom_line() + geom_point() + theme_classic() + geom_errorbar(aes(ymin=media-1.96*es, ymax=media+1.96*es), width=.1)
#

Dopo avere aperto con windows() una nuova finestra grafica vediamo che la novità rispetto al grafico a linee iniziale, a parte rappresentare in ordinate per ciascun tempo non più i singoli valori di concentrazione bensì la loro media ricavata dalla tabella mydata, è rappresentata dalla funzione geom_errorbar() che con gli argomenti ymin e ymax provvede ad aggiungere al grafico per ciascun tempo i limiti di confidenza al 95% della media, calcolati sottraendo e sommando alla media l'errore standard es moltiplicato per 1.96.

Ed ecco il grafico risultante che, vale la pena di sottolinearlo, fornisce una chiave di lettura cruciale per l'interpretazione dei risultati in quanto di ciascuna media riporta il grado di incertezza. 


Conclusione: anche nel caso assai semplice di un grafico a linee – che come detto può essere realizzato con le funzioni base di R [1], ma sicuramente con maggior difficoltà – il pacchetto ggplot2 fornisce un esempio di versatilità, di rapidità di realizzazione e di ottimi risultati grafici: quanto di meglio per essere invogliati al suo impiego e al suo approfondimento [3]. 


----------

[1] Vedere il post Grafici a linee.

[2] Fate click su ggplot2 nelle Parole chiave o digitate ggplot2 nella casella Cerca nel blog quindi fate click su Cerca.

[3] Vedere il link al manuale di riferimento su:
https://cran.r-project.org/web/packages/ggplot2/index.html

domenica 20 gennaio 2019

Grafici a linee (line chart)

Vediamo come rappresentare i grafici a linee impiegando una funzione e un set di dati inclusi nella installazione base di R. Si tratta della funzione plot() [1], utile per una molteplicità di rappresentazioni

Se nella Console di R digitate data() potete vedere l'elenco dei set dati che sono caricati automaticamente all'avvio del programma e che include il set di dati WorldPhones qui impiegato.

Copiate e incollate nella Console di R questo script e premete ↵ Invio:

# GRAFICI A LINEE set di dati di R
#
mydata <- data.frame(WorldPhones) # trasforma il set di dati WorldPhones in dataframe
mydata # mostra i dati
#
windows() # apre una nuova finestra
#
# traccia il grafico a linee per la prima variabile
plot(mydata$N.Amer, type="o", pch=19, lty=1, col="red", ylim=c(0,80000), axes=FALSE, ann=FALSE)
# sovrappone i grafici a linee per le variabili successive
lines(mydata$Europe, type="o", pch=20, lty=2, col="blue")
lines(mydata$Asia, type="o", pch=21, lty=3, col="brown")
lines(mydata$S.Amer, type="o", pch=22, lty=4, col="darkolivegreen")
lines(mydata$Oceania, type="o", pch=23, lty=5, col="gold1")
lines(mydata$Africa, type="o", pch=24, lty=6, col="green4")
lines(mydata$Mid.Amer, type="o", pch=25, lty=7, col="cornflowerblue")
#
# traccia gli assi con le rispettive scale e riporta le etichette sull'asse orizzontale
axis(1, at=1:7, labels=c("1951","1956","1957","1958","1959","1960","1961"))
axis(2, las=1, at=20000*0:80000)
#
# riporta titolo ed etichetta dell'asse delle x
title(main="Numero di apparecchi telefonici nel mondo", col.main="black", font.main=1)
title(xlab="Anno della rilevazione", col.lab="black")
#
# riporta una legenda con i nomi delle variabili e i simboli delle linee impiegati
legend(5, 70000, c("Nord America", "Europa", "Asia", "Sud America", "Oceania", "Africa", "Centro America"), cex=0.8, col=c("red","blue", "brown", "darkolivegreen", "gold1", "green4", "cornflowerblue"), pch=19:25, lty=1:7, bty="y")
#

Nella prima riga di codice dal set di dati WorldPhones con la funzione data.frame() viene creata una tabella (dataframe) che viene assegnata (<-) all'oggetto mydata, quindi con mydata sono mostrati i dati importati:

> mydata # mostra i dati
     N.Amer Europe Asia S.Amer Oceania Africa Mid.Amer
1951  45939  21574 2876   1815    1646     89      555
1956  60423  29990 4708   2568    2366   1411      733
1957  64721  32510 5230   2695    2526   1546      773
1958  68484  35218 6662   2845    2691   1663      836
1959  71799  37598 6856   3000    2868   1769      911
1960  76036  40341 8220   3145    3054   1905     1008
1961  79831  43173 9053   3338    3224   2005     1076

che sono rappresentati dalle rilevazioni, effettuate tra l'anno 1951 e l'anno 1961, del numero di apparecchi telefonici, suddivisi per le principali aree geografiche del mondo.

Dopo avere aperto la finestra grafica con windows() nel successivo blocco di codice viene generato mediante la funzione plot() il grafico a linee che riporta in ascisse (x) i descrittori delle righe (1951, 1952, … 1961) e impiega come argomenti:
mydata$N.Amer la prima variabile del set di dati, posta in ordinate (y);
type="o" che consente di sovrascrivere i grafici successivi;
pch=19 quale dei simboli dei punti di R deve essere impiegato per i punti da rappresentare;
lty=1 quale degli stili delle linee di R deve essere impiegato per la linea da rappresentare;
col="red" quale colore impiegare per i punti e le linee da rappresentare;
ylim=c(0,80000) limiti inferiore e superiore dell'asse delle y;
axes=FALSE che indica di non rappresentare gli assi del grafico che verranno poi configurati manualmente nelle righe successive;
ann=FALSE che indica di non rappresentare titolo ed etichette dell'asse delle x e delle y che verranno poi configurati manualmente nelle righe successive.

Al grafico così creato, con le sei righe di codice successive sono sovrapposti i grafici a linee delle altre sei variabili che vogliamo rappresentare: Europe, Asia, S.Amer, Oceania, Africa, Mid.Amer.

Viene poi tracciato l'asse delle x axis(1....) ponendo nelle posizioni che vanno dalla 1 alla 7 (at=1:7) le etichette "1951", "1956", "1957", "1958", "1959", "1960", "1961" riportate nell'argomento labels. Per l'asse delle ordinate axis(2....) le tacche sono tracciate in orizzontale (las = 1) ogni 20000 (at=20000) per la scala che va da 0 a 80000 (0:80000).

Titolo ed etichetta dell'asse delle x riportati nel blocco di codice successivo non richiedono particolari commenti.

Infine la funzione legend() consente di aggiungere una legenda, che prevede i seguenti argomenti:
5, 70000 sono le coordinate x e y alle quali viene posizionato l'angolo superiore sinistro della legenda;
"Nord America", "Europa", "Asia", "Sud America", "Oceania", "Africa", "Centro America" sono i nomi da riportare;
cex.axis = 0.8 specifica la dimensione dei caratteri da impiegare;
"red","blue", "brown", "darkolivegreen", "gold1", "green4", "cornflowerblue" sono i colori di R che ovviamente riprendono nell'ordine quelli delle linee riportate nel grafico;
pch=19:25 sono i simboli dei punti di R impiegati nel grafico;
lty=1:7 sono gli stili delle linee di R impiegati nel grafico;
bty="y" che è l'opzione di default della funzione plot() e consente di tracciare il riquadro contenente la legenda, viene qui riportato per ricordare che con bty="n" è possibile eliminarlo.


Da notare che l'esempio è stato sviluppato esclusivamente per illustrare le funzioni e gli argomenti per rappresentare un grafico a linee. Ma si fa notare nel set di dati fornito, tra il 1951 e il 1956 intercorrono 5 anni, mentre gli intervalli successivi sono di un anno: questo distorce la rappresentazione, aumentando la pendenza del primo segmento di retta rispetto al reale. Ovviamente si raccomanda di non introdurre mai distorsioni di questo o di altro genere nella rappresentazione dei propri dati.

I grafici a linee vengono spesso impiegati per rappresentare variabili con pochi dati: potrebbe pertanto essere utile disporre di un esempio nel quale i dati sono inseriti manualmente. Copiate e incollate nella Console di R questo script e premete ↵ Invio:

# GRAFICI A LINEE dataframe costruito manualmente
#
N.Amer <- c(45939, 60423, 64721, 68484, 71799, 76036, 79831) # vettore con la prima variabile
Europe <- c(21574, 29990, 32510, 35218, 37598, 40341, 43173) # vettore con la seconda variabile
Asia <- c(2876, 4708, 5230, 6662, 6856, 8220, 9053) # vettore con la terza variabile
S.Amer <- c(1815, 2568, 2695, 2845, 3000, 3145, 3338) # vettore con la quarta variabile
Oceania <- c(1646, 2366, 2526, 2691, 2868, 3054, 3224) # vettore con la quinta variabile
Africa <- c(89, 1411, 1546, 1663, 1769, 1905, 2005) # vettore con la sesta variabile
Mid.Amer <- c(555, 733, 773, 836, 911, 1008, 1076) # vettore con la settima variabile
mydata <- data.frame(N.Amer, Europe, Asia, S.Amer, Oceania, Africa, Mid.Amer) # combina i vettori nel dataframe mydata
row.names(mydata) <- c(1951, 1956, 1957, 1958, 1959, 1960, 1961) # aggiunge i nomi delle righe
mydata # mostra i dati
#
windows() # apre una nuova finestra
#
# traccia il grafico a linee per la prima variabile
plot(N.Amer, type="o", pch=19, lty=1, col="red", ylim=c(0,80000), axes=FALSE, ann=FALSE)
# sovrappone i grafici a linee per le variabili successive
lines(Europe, type="o", pch=20, lty=2, col="blue")
lines(Asia, type="o", pch=21, lty=3, col="brown")
lines(S.Amer, type="o", pch=22, lty=4, col="darkolivegreen")
lines(Oceania, type="o", pch=23, lty=5, col="gold1")
lines(Africa, type="o", pch=24, lty=6, col="green4")
lines(Mid.Amer, type="o", pch=25, lty=7, col="cornflowerblue")
#
# traccia gli assi con le rispettive scale e riporta le etichette sull'asse orizzontale
axis(1, at=1:7, labels=c("1951", "1956", "1957", "1958", "1959", "1960", "1961"))
axis(2, las=1, at=20000*0:80000)
#
# riporta titolo ed etichetta dell'asse delle x
title(main="Numero di apparecchi telefonici nel mondo", col.main="black", font.main=1)
title(xlab="Anno della rilevazione", col.lab="black")
#
# riporta una legenda con i nomi delle variabili e i simboli delle linee impiegati
legend(5, 70000, c("Nord America", "Europa", "Asia", "Sud America", "Oceania", "Africa", "Centro America"), cex=0.8, col=c("red","blue", "brown", "darkolivegreen", "gold1", "green4", "cornflowerblue"), pch=19:25, lty=1:7, bty="y")
#

Dopo avere inserito mediante la funzione c() i valori delle singole variabili, questi sono combinati mediante la funzione data.frame() nella tabella (dataframe) mydata, alla quale sono infine aggiunti con la funzione row.names() i nomi delle righe che verranno riportati sull'asse orizzontale del grafico. Il resto del codice è identico a quello dello script precedente.

Da notare come ultima cosa che in quest'ultimo script avendo eseguito la funzione row.names() si possono impiegare direttamente i nomi delle variabili (ad esempio N.Amer) senza eseguire la funzione attach(), mentre nello script precedente, nel quale la funzione attach() non è stata eseguita, si è reso necessario specificare per le variabili il nome completo (ad esempio mydata$N.Amer).

Entrambi gli script possono essere facilmente riutilizzati, il primo sostituendo al set di dati WorldPhones i propri dati, organizzati in modo analogo, il secondo adattando opportunamente numero, nomi e valori delle variabili che confluiscono nell'oggetto mydata.

Nota bene: in alternativa alle funzioni di base qui illustrate è possibile realizzare grafici a linee anche impiegando le funzioni del pacchetto ggplot2, per questo rimando al post Grafici a linee con ggplot.


----------

[1] Digitate help(plot) nella Console di R per la documentazione della funzione plot() e digitate help(nomedellafunzione) nella Console di R per la documentazione delle altre funzioni impiegate nello script.