mercoledì 15 settembre 2021

Adattare i margini a un grafico

Può capitare di realizzare un grafico per il quale non sono adeguati i margini previsti di default per la finestra grafica di R. Vediamo il problema e una possibile soluzione.

Accertatevi innanzitutto di avere installato il pacchetto DAAG che contiene i dati che ci servono, o in alternativa procedete come indicato nel post Il set di dati ais nel quale trovate anche illustrato il significato dei dati impiegati [1].

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

# ADATTARE I MARGINI A UN GRAFICO
#
library(DAAG) # carica il pacchetto DAAG che include il set di dati ais
mydata <- ais[,c(5)] # salva in mydata i valori della variabile contenuta nella colonna 5 della tabella ais
#
par("mar") # mostra i margini di default della finestra grafica
#
# traccia istogramma e kernel density plot sovrapposti, con i margini di default
#
hist(mydata, main="Istogramma e kernel density plot", xlab="Ferritina in µg/L", ylab = "Numero dei casi per classe", xlim = c(0,250)) # traccia l'istogramma
par(new=TRUE, ann=FALSE) # consente la sovrapposizione del grafico successivo
plot(density(mydata), main="Kernel density plot", xlab="Ferritina in µg/L", ylab = "Frequenza", xlim = c(0,250), yaxt="n", col="red") # traccia il kernel density plot
axis(4, col.ticks="red", col.axis="red") # riporta l'asse delle y sulla destra
mtext("Stima kernel di densità", side=4, line=3) # aggiunge la legenda all'asse delle y sulla destra
#
# traccia istogramma e kernel density plot sovrapposti, con margine destro allargato
#
windows() # apre e inizializza una nuova finestra grafica
par(mar=c(5.1,4.1,4.1,5.1)) # aumenta il margine destro da 2.1 a 5.1
#
hist(mydata, main="Istogramma e kernel density plot", xlab="Ferritina in µg/L", ylab = "Numero dei casi per classe", xlim = c(0,250)) # traccia l'istogramma
par(new=TRUE, ann=FALSE) # consente la sovrapposizione del grafico successivo
plot(density(mydata), main="Kernel density plot", xlab="Ferritina in µg/L", ylab = "Frequenza", xlim = c(0,250), yaxt="n", col="red") # traccia il kernel density plot
axis(4, col.ticks="red", col.axis="red") # riporta l'asse delle y sulla destra
mtext("Stima kernel di densità", side=4, line=3) # aggiunge la legenda all'asse delle y sulla destra
#
par(mar=c(5.1,4.1,4.1,2.1)) # ripristina i margini di default
#

In questo caso il problema è causato dal desiderio di riportare sullo stesso grafico l'istogramma e il kernel density plot di una variabile. La scala sull'asse delle ascisse x è identica per entrambi, ma
→ nel caso dell'istogramma dobbiamo riportare sull'asse delle ordinate y il numero di casi per ciascuna delle classi in cui è suddiviso;
→ nel caso del kernel density plot dobbiamo riportare sull'asse delle ordinate y la stima kernel di densità espressa in termini di probabilità.

La soluzione più ovvia è di riportare due scale delle ordinate, una sulla sinistra riferita all'istogramma, e una sulla destra riferita al kernel density plot (o viceversa, non importa). Qui riportiamo il kernel density plot in rosso e i relativi valori sulla scale delle ordinate di destra nello stesso colore.

Con la prima parte dello script viene generato questo primo grafico con istogramma e kernel density plot sovrapposti


che impiega i margini di default della finestra grafica, i quali, richiamati nella terza riga di codice mediante la funzione par("mar")

> par("mar") # mostra i margini di default
[1] 5.1 4.1 4.1 2.1

sono rispettivamente 5.1 per il margine inferiore, 4.1 per il margine sinistro, 4.1 per il margine superiore e 2.1 per il margine destro, espressi come numero di righe (per i dettagli digitare help(par) nella Console di R).

Come si vede la funzione mtext() riporta la legenda "Stima kernel di densità" dell'asse delle y sulla destra (side=4) nella terza riga di testo (line=3), ma questa non compare nella finestra grafica.

Nella seconda parte dello script il problema viene corretto impiegando lo stesso identico codice, ma facendolo precedere dalla funzione

par(mar=c(5.1,4.1,4.1,5.1))

che aumenta il margine destro dal valore di default di 2.1 a 5.1 riducendo lievemente la larghezza del grafico e lasciando così sulla destra spazio adeguato per la legenda dell'asse delle y, che nel grafico precedente non era visibile, e ottenendo questo secondo grafico [2].


Lo script si conclude con la funzione par(mar=c(5.1,4.1,4.1,2.1)) che ripristina i valori di default dei margini (un passo non obbligatorio, ma altamente raccomandato).

La soluzione riportata può essere facilmente adattata ai diversi casi che si possono presentare nella pratica.


----------

[1] Qui impieghiamo i valori - contenuti nella colonna 5 della tabella ais (vedere la seconda riga di codice dello script) - della variabile ferritina, una proteina che, pur con alcune limitazioni, fornisce una misura dei depositi di ferro presenti nell'organismo, necessari per garantire una adeguata produzione di emoglobina.

[2] Una banalità per chi non fosse ancora abituato a R: quando si esegue lo script, il secondo grafico viene sovrapposto al primo, quindi è necessario minimizzare la finestra del secondo grafico o afferrarla con il mouse e spostarla per vedere il grafico sottostante.


Nessun commento:

Posta un commento