lunedì 3 marzo 2025

Gradi centigradi o gradi Celsius?

Se è vero che la statistica è la tecnica che consente di fornire un supporto scientifico alle evidenze fornite dalle misure, ci sono dal punto di vista metodologico, nelle misure da sottoporre ad analisi statistica, quattro aspetti sull'importanza dei quali non mi stancherò mai di richiamare l'attenzione [1], uno dei quali è:
→ l'utilizzo di un sistema di unità di misura razionale, documentato e condiviso quale è il Sistema internazionale di unità (SI) –  adottato per legge anche in Italia – applicandone integralmente e senza eccezioni le indicazioni.

Per l'appunto: il Sistema Internazionale di unità (SI) è stato adottato per legge in Italia nel 1982, e le successive modifiche sono state adottate per legge nel 2001, nel 2009 e nel 2020 [2]. 

Ma perché ricordare una cosa che dovrebbe essere arcinota?

Perché un bel giorno ricevo una mail che contiene, tra le anteprime giornalistiche del quotidiano al quale sono abbonato, questa immagine e il suo commento.


Faccio una rapida ricerca su Google e trovo che se le espressioni "grado celsius" e "gradi celsius" sono citate 737 000 volte, le espressioni 
"grado centigrado" e "gradi centigradi" sono citate ben 268 000 volte: insomma, più di una volta su quattro.

Ma il Sistema Internazionale di unità (SI) non prevede il grado centigrado!

La brochure ufficiale che illustra il SI [3] riporta tra le molte altre cose le sette unità di base del SI, che includono la temperatura termodinamica espressa in kelvin (K):


(a) I simboli delle grandezze sono generalmente singole lettere dell'alfabeto Latino o Greco, sono in carattere corsivo (in francese "italique"; in inglese "italic") e sono raccomandazioni.

(b) I simboli delle unità sono in carattere tondo (in francese "romain"; in inglese "roman") e sono mandatori.

(c) Dopo i simboli non si deve mettere il punto (kg e non kg. ovvero mol e non mol. e così via): si tratta appunto di simboli, e non di abbreviazioni.

Sempre come riportato nella brochure, dalle unità di base del SI si ricavano le ventidue unità SI con nomi e simboli speciali che seguono e che includono la temperatura Celsius espressa in gradi Celsius (°C):

Il valore numerico di una temperatura Celsius (t) espressa in gradi Celsius (°C) è collegato al valore numerico di una temperatura termodinamica (T) espressa in kelvin (K) dalla relazione

t/°C = T/K - 273.15  [4]


Da notare che in questo modo il valore numerico di una differenza (o intervallo) di temperatura è lo stesso quando espresso in kelvin o in gradi Celsius: se una temperatura aumenta (ad esempio) di 10 kelvin, aumenta anche esattamente di 10 gradi Celsius. Mentre posso dire che questa mattina nel giardino di casa il mio termometro segnava "una temperatura di 0 gradi [Celsius]" piuttosto che "una temperatura di 273.15 kelvin". 

Come riportato anche nella SI Brochure [3] la decisione di adottare il Sistema Internazionale di unità (SI) è stata presa durante la 9ª CGPM (la Conferenza Generale dei Pesi e Misure ovvero il "parlamento" nel quale i rappresentanti nazionali discutono e adottano le decisioni in merito alle convenzioni in campo metrologico) che si è tenuta nel 1948. In quella occasione si è anche deciso di adottare – in luogo del fino ad allora denominato "grado centesimale" o "grado centigrado" – il "grado Celsius", in onore dello svedese Anders Celsius che nel 1742 aveva pubblicato, negli Atti della Accademia Reale Svedese di Scienze, la proposta di adottare per la misura della temperatura una scala centesimale con due punti fissi, il punto 0 alla temperatura di ebollizione dell'acqua e il punto 100 alla temperatura di congelamento dell'acqua [5]. 

Fu il fisico francese Jean-Pierre Christin nel 1743 a proporre un termometro a mercurio che scambiava tra loro i valori assegnati ai due punti fissi ponendo a 0 gradi la temperatura di congelamento e a 100 gradi la temperatura di ebollizione dell'acqua come descritto in questo documento [6] a p. 250: "En juillet 1743, il fait connaître au public, par la voie des journaux (Mercure de France, etc., etc.), son thermomètre centigrade à mercure, sous le nom de Thermomètre de Lyon, divisé selon la mesure de la dilatation du mercure..." e alle pp. 259-260: "... le zéro vrai du thermomètre de Celsius marquait l'eau bouillante, tandis que le 100 ͤ degré correspondait à la congélation, ce qui est précisément l'inverse de la graduation lyonnaise".

La stessa scala l'adottò, probabilmente senza sapere del lavoro di Christin, Carlo Linneo tre anni dopo il lavoro del suo connazionale Celsius. Infatti nel suo Hortus upsaliensis del 1745 a p. 23 Linneo riporta in una nota: "Thermometrum nostrum est 0 in puncto congelationis et numerat 100 ad gradus aquæ coquentis[7].

Nella prima metà del '700 la misura della temperatura era considerata dagli scienziati un obiettivo molto importante, se in precedenza:
 già nel 1724 il tedesco Daniel Gabriel Fahrenheit, ispirandosi a studi ancora precedenti del danese Ole Christensen Rømer, aveva proposto l'impiego del mercurio e di una scala delle temperature [8] che, dopo varie modifiche, è diventata l'attuale scala Fahrenheit (il grado Fahrenheit, con il simbolo °F, è ammesso per l'uso corrente negli USA, nei quali comunque si impiegano in campo scientifico le unità del SI al quale gli USA aderiscono), che fissa a 32 gradi il punto di congelamento dell'acqua e a 212 gradi il punto di ebollizione, con un intervallo di 180 gradi tra le due temperature;
 nel 1732 il francese René-Antoine Ferchault de Réaumur aveva proposto un termometro ad alcool con un intervallo di 80 gradi: "Il s'est déterminé à faire remplir les Thermometres d'un Esprit de Vin, dont le volume étant de 1000 parties, lorsqu'il a pris le froid de l'eau qui commence à se geler, devient 1080, lorsqu'il a pris le plus grand degré de chaleur que l'eau puisse lui donner sans le faire boüillir[9], in un lavoro cui si era ispirato Christin.

Infine non dobbiamo dimenticare i contributi di scienziati italiani in quelli che erano stati i primordi nella misura delle temperature, con:
 il termoscopio, lo strumento messo a punto da Galileo Galilei nel 1597 che a livello sostanzialmente qualitativo "evidenziava le variazioni della densità dell'aria prodotte dalle variazioni di temperatura" [10];
 vari tipi di termometro tra cui il termometro a fiala [11] – descritto nel 1666 nei verbali dell'Accademia del Cimento [12] come "... un Termometro ma piu pigro, e infingardo di tutti gli altri. Poichè dove quegli per ogni poco, che l'aria ſi ſtemperi veggonſi ſubito alterare, queſt'altro non è tanto veloce, ed a muoverlo vi vuol'altro che minime, ed inſenſibili differenze. Nulladimeno perchè di queſti ancora, n'è andati in diuverſe parti dentro, e fuori d'Italia; ſi dira brevemente in queſto luogo della loro fabbrica…" – che appartiene alla fase della misura semiquantitativa della temperatura, effettuata in questo caso mediante ampolle colorate che si muovono su e giù al cambiare della densità (che è funzione della temperatura) del mezzo in cui sono immerse. Nell'immagine a destra una versione attuale, impropriamente denominata "termometro galileiano", del termometro a fiala indicato come V nella tavola di sinistra, tratta da [12]: i cinque termometri da I a V illustrati erano riempiti con "il ſottiliſsimo ſpirito del vino, o acquarzente". Come VI nella tavola è indicato invece uno strumento che serviva "per riconoscere le differenze dell'umido nell'aria".


Conclusione: il mio sogno nel cassetto, uno dei tanti? Non vedere mai più temperature riportate in gradi centigradi. Per favore (e per razionalità scientifica, oltre che per una norma vigente) o parliamo di kelvin (K), ma questo avviene in ambito scientifico, o parliamo in alternativa di gradi Celsius (°C), cioè nei termini corretti delle unità di misura della temperatura nelle quali dobbiamo esprimerci [13]. E in ogni caso chiediamo che i dati da elaborare statisticamente siano sempre espressi con le grandezze, le denominazioni, le unità di misura, i simboli, i multipli e i sottomultipli del SI, indirizzando l'interlocutore al bisogno anche alle JCGM Publications: Guides in Metrology [14].


----------

[2] Il Sistema Internazionale di unità (SI) diviene legale in Italia nel 1982, le successive modifiche sono recepite nel 2001, nel 2009 e nel 2020, questa è la normativa aggiornata a inizio 2024, che include la correzione riportata a livello comunitario nel 1984:
- DECRETO DEL PRESIDENTE DELLA REPUBBLICA 12 agosto 1982, n. 802. Attuazione della direttiva (CEE) n. 80/181 relativa alle unita' di misura. GU Serie Generale n.302 del 03-11-1982 - Suppl. Ordinario.
https://www.gazzettaufficiale.it/eli/id/1982/11/03/082U0802/sg
- DIRETTIVA DEL CONSIGLIO del 18 dicembre 1984 che modifica la direttiva 80/181/CEE per il ravvicinamento delle legislazioni degli Stati membri relative alle unità di misura.
https://eur-lex.europa.eu/legal-content/IT/TXT/PDF/?uri=CELEX:31985L0001
- DECRETO 29 gennaio 2001. Attuazione della direttiva 1999/103/CE che modifica la direttiva 80/181/CEE sul riavvicinamento delle legislazioni degli Stati membri relative alle unita' di misura. GU Serie Generale n.27 del 02-02-2001 
https://www.gazzettaufficiale.it/eli/id/2001/02/02/001A1152/sg
- DECRETO 29 ottobre 2009. Attuazione della direttiva 2009/3/CE del Parlamento europeo e del Consiglio dell'11 marzo 2009 che modifica la direttiva 80/181/CEE del Consiglio sul riavvicinamento delle legislazioni degli Stati membri riguardo alle unita' di misura. (09A13580). GU Serie Generale n.273 del 23-11-2009 
https://www.gazzettaufficiale.it/eli/id/2009/11/23/09A13580/sg
- DECRETO 7 aprile 2020. Attuazione della direttiva (UE) 2019/1258 della Commissione del 23 luglio 2019 che modifica, ai fini dell'adattamento al progresso tecnico, l'allegato della direttiva 80/181/CEE del Consiglio per quanto riguarda le definizioni delle unita' SI di base.
https://www.gazzettaufficiale.it/eli/id/2020/05/09/20A02529/sg

[3] SI Brochure: The International System of Units (SI)
https://www.bipm.org/en/publications/si-brochure

[4] La spiegazione della notazione impiegata è riportata nella SI Brochure [3] e a pag. 52 del mio ebook su Grandezze e unità di misura che può essere scaricato a questi link:
https://www.academia.edu/41041923/
https://play.google.com/books/reader?id=GciVDwAAQBAJ
https://www.bayes.it/SI.pdf

[5] Celsius, Anders (1742). Observationer om twänne beständiga grader på en thermometer. Kungliga Svenska Vetenskapsakademiens Handlingar (3): 171–180.
https://archive.org/stream/kungligasvenskav1317kung

[6] SUR L'INVENTION DU THERMOMÈTRE CENTIGRADE A MERCURE, Faite à Lyon par M. CHRISTIN. NOTICE LUE A LA SOCIÉTÉ D'AGRICULTURE DE LYON, Dans la séance du 4 juillet 1845. In: ANNALES DES SCIENCES PHYSIQUES ET NATURELLES, D'AGRICULTURE ET D'INDUSTRIE, PUBLIÉES PAR La Société royale d'Agriculture, etc., DE LYON. TOME VIII. 1845.
https://play.google.com/books/reader?id=o4g9AQAAMAAJ

[7] Hortus upsaliensis, 1745.
https://ia800503.us.archive.org/16/items/naucler-1745/Naucler1745.pdf

[8] VIII. Experimenta & observationes de congelatione aquæ in vacuo factæ a D. G. Fahrenheit, R. S. S. In: Philosophical Transactions of the Royal Society of London, Volume 33, Issue 382. Published: 30 April 1724.
https://doi.org/10.1098/rstl.1724.0016

[9] Explication des principes établis par M. de Reaumur, pour la construction des thermometres dont les degrés soient comparables. 1732.
https://gallica.bnf.fr/ark:/12148/bpt6k6535672b/

[10] Museo Galileo. Termoscopio.
https://catalogo.museogalileo.it/oggetto/Termoscopio.html

[11] Museo Galileo. Termometri a fiala.
https://catalogo.museogalileo.it/oggetto/TermometriFiala.html

[12] DI NATVRALI ESPERIENZE FATTE NELL'ACCADEMIA DEL CIMENTO SOTTO LA PROTEZIONE DEL SERENISSIMO PRINCIPE LEOPOLDO DI TOSCANA E DESCRITTE DAL SEGRETARIO DI ESSA ACCADEMIA. IN FIRENZE. MDCLXVI. 
https://play.google.com/books/reader?id=BcCpGiXkRKsC

[13] Notare tra l'altro che, poiché la legge non ammette ignoranza, un atto legale che riporta una temperatura espressa in "gradi centigradi" potrebbe essere impugnato.

[14] Vedere i documenti:
 GUM: Guide to the Expression of Uncertainty in Measurement
 VIM: International Vocabulary of Metrology
https://www.bipm.org/en/committees/jc/jcgm/publications

martedì 25 febbraio 2025

Grafici a linee (line chart) con ggplot

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

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 identificati con i numeri da 1 a 6 (ai quali 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. Ed ecco i dati:

   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

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
#
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.

#
# aggrega i dati per ciascun tempo
#
library(plotrix) # carica il pacchetto per il calcolo dell'errore standard
#
mydata <- aggregate(conc~time, data=Indometh, FUN=function(x) c(mean=mean(x), se=std.error(x))) # calcola media ed errore standard della concentrazione per ciascun tempo
#
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)

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

mentre per semplificare e rendere più leggibile il codice successivo media (conc.mean) ed errore standard (conc.se) sono salvati nei due vettori media ed es.

Dopo questo necessario passo intermedio possiamo di nuovo tornare al 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
#
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 sola novità rispetto al grafico a linee di base iniziale è rappresentata dalla funzione geom_errorbar() che con gli argomenti ymin e ymax provvede ad aggiungere al grafico, rispettivamente sottraendo e sommando alla media l'errore standard es moltiplicato per 1.96, i limiti di confidenza al 95% della media

Ed ecco il grafico risultante che, vale la pena di sottolinearlo, fornisce una chiave di lettura cruciale per l'interpretazione dei risultati. 


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, che rappresentano un invito 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



giovedì 16 gennaio 2025

Come realizzare colori personalizzati [2]

Per predisporre colori personalizzati si possono impiegare queste tre funzioni:
→ rgb(red, green, blue, alpha) che genera i colori regolando il livello di intensità dei tre colori fondamentali rosso (red), verde (green) e blu (blue) e la trasparenza del colore (alpha);
→ hsv(h, s, v, alpha) che genera i colori regolando colore (h), saturazione (s), luminosità (v) e trasparenza (alpha);
→ hcl(h, c, l, alpha) che genera i colori regolando colore (h), cromaticità (c), luminanza (l) e trasparenza (alpha).

La funzione rgb() è trattata estesamente in un post a parte [1], qui vediamo invece le altre due, e vediamo poi come combinare i risultati di tutte e tre in palette personalizzate ovvero tavolozze che si possono impiegare per applicare automaticamente colori differenti alle diverse componenti di un grafico.

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

# PERSONALIZZAZIONE DEI COLORI con la funzione hsv()
# regolando colore h, saturazione s, luminosità v, trasparenza alpha
#
mydata <- rnorm(5000, mean=0, sd=1) # genera cinquemila valori con media=0, ds=1
windows() # apre e inizializza una nuova finestra grafica
par(mfrow=c(4,4)) # suddivisione la finestra grafica in 4 righe per 4 colonne
# colore h
hist(mydata, col=hsv(h=0.9, s=1.0, v=1.0)) 
hist(mydata, col=hsv(h=0.6, s=1.0, v=1.0)) 
hist(mydata, col=hsv(h=0.4, s=1.0, v=1.0)) 
hist(mydata, col=hsv(h=0.1, s=1.0, v=1.0)) 
# saturazione s
hist(mydata, col=hsv(h=0.6, s=0.9, v=1.0))  
hist(mydata, col=hsv(h=0.6, s=0.6, v=1.0)) 
hist(mydata, col=hsv(h=0.6, s=0.4, v=1.0)) 
hist(mydata, col=hsv(h=0.6, s=0.1, v=1.0)) 
# luminosità v
hist(mydata, col=hsv(h=0.4, s=1.0, v=0.9, alpha=0.5)) 
hist(mydata, col=hsv(h=0.4, s=1.0, v=0.6, alpha=0.5)) 
hist(mydata, col=hsv(h=0.4, s=1.0, v=0.4, alpha=0.5)) 
hist(mydata, col=hsv(h=0.4, s=1.0, v=0.1, alpha=0.5)) 
# trasparenza alpha
hist(mydata, col=hsv(h=0.1, s=1.0, v=1.0, alpha=0.9)) 
hist(mydata, col=hsv(h=0.1, s=1.0, v=1.0, alpha=0.6)) 
hist(mydata, col=hsv(h=0.1, s=1.0, v=1.0, alpha=0.4)) 
hist(mydata, col=hsv(h=0.1, s=1.0, v=1.0, alpha=0.1)) 
#

Nella funzione hsv(h, s, v, alpha) gli argomenti:
→ colore (h)
→ saturazione (s)
→ luminosità (v)
→ trasparenza (alpha)
possono assumere solamente valori compresi tra 0 e 1.

Allo scopo di illustrare i risultati forniti dalla funzione con istogrammi colorati:
→ nella prima riga di istogrammi è stato fatto variare l'argomento colore (h);
→ nella seconda riga è stato fatto variare l'argomento saturazione (s)
→ nella terza riga è stato fatto variare l'argomento luminosità (v);
→ nell'ultima riga è stato fatto varare l'argomento trasparenza (alpha).

Come si vede i colori della prima riga, con il massimo di saturazione e di luminosità e senza alcuna trasparenza, sono vividi. Gli altri colori di base possibili possono ovviamente essere visualizzati variando opportunamente i valori di (h), mentre si lasciano la combinazione dei diversi valori possibili per i quattro argomenti e i relativi risultati in termine di colore all'eventuale interesse e alla sperimentazione.


Da notare infine che i dati impiegati negli esempi sono generati ex-novo ogniqualvolta viene eseguito lo script, pertanto i grafici saranno sempre lievemente diversi gli uni dagli altri e da quelli qui riportati. Inoltre differenze più o meno importanti nel colore sono determinate dai monitor (per i quali esistono metodi di taratura in grado di ridurle) e nel caso delle stampe dal fatto che le stampanti impiegano la sintesi sottrattiva del colore (ciano, giallo e magenta sommati danno il nero).

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

# PERSONALIZZAZIONE DEI COLORI con la funzione hcl()
# regolando colore h, cromaticità c, luminanza l e trasparenza alpha
#
mydata <- rnorm(5000, mean=0, sd=1) # genera cinquemila valori con media=0, ds=1
windows() # apre e inizializza una nuova finestra grafica
par(mfrow=c(4,4)) # suddivisione la finestra grafica in 4 righe per 4 colonne 
# colore h
hist(mydata, col=hcl(h=60))
hist(mydata, col=hcl(h=120)) 
hist(mydata, col=hcl(h=240))
hist(mydata, col=hcl(h=300))
# cromaticità c
hist(mydata, col=hcl(h=120, c=100, l=40))  
hist(mydata, col=hcl(h=120, c=100, l=60)) 
hist(mydata, col=hcl(h=120, c=100, l=80)) 
hist(mydata, col=hcl(h=120, c=100, l=90)) 
# luminanza l
hist(mydata, col=hcl(h=240, c=60, l=40))  
hist(mydata, col=hcl(h=240, c=80, l=60)) 
hist(mydata, col=hcl(h=240, c=100, l=80)) 
hist(mydata, col=hcl(h=240, c=120, l=90)) 
# trasparenza alpha
hist(mydata, col=hcl(h=300, c=90, l=40, alpha=0.5))  
hist(mydata, col=hcl(h=300, c=90, l=60, alpha=0.5)) 
hist(mydata, col=hcl(h=300, c=90, l=80, alpha=0.5)) 
hist(mydata, col=hcl(h=300, c=90, l=90, alpha=0.5)) 
#

Nella funzione hcl(h, c, l, alpha) che genera i colori:
→ il colore (h) può assumere valori compresi tra 0 e 360;
→ il limite superiore della cromaticità (c) dipende dai valori di colore e luminanza;
→ la luminanza (l) può assumere valori compresi tra 0 e 100;
→ la trasparenza (alpha) può assumere valori compresi tra 0 e 1.

I colori della prima riga di istogrammi, che impiegano i valori di default
c=35 e l=85, mettono in evidenza la possibilità di ottenere con questa funzione colori pastello che è difficile trovare tra i 657 colori forniti nel pacchetto base di R [2].

Agendo su cromaticità (seconda riga) e luminanza (terza riga) si possono ottenere colori più saturi. Anche in questo caso si lasciano la combinazione dei diversi valori possibili per i quattro argomenti e i relativi risultati in termine di colore all'eventuale interesse e alla sperimentazione.


Una volta ottenuti i colori desiderati, si possono impiegare le funzioni che li hanno generati per ottenere i rispettivi codici esadecimali, che sono quelli che R impiega. Farlo è semplicissimo in quanto le tre funzioni per la generazione di colori, come avviene a titolo di esempio con queste tre righe di codice,

# generazione del codice esadecimale del colore
#
rgb(0.7, 0.2, 0.3, 0.5)
hsv(h=0.6, s=0.4, v=1.0)
hcl(h=120, c=100, l=60)
#

quando sono eseguite singolarmente 

> rgb(0.7, 0.2, 0.3, 0.5)
[1] "#B3334D80"
> hsv(h=0.6, s=0.4, v=1.0)
[1] "#99C2FF"
> hcl(h=120, c=100, l=60)
[1] "#39A700"

forniscono direttamente il codice esadecimale corrispondente, che può poi essere impiegato direttamente come valore dell'argomento col. Da notare che in questo esempio il codice esadecimale "#B3334D80" prodotto con la funzione rgb() ha due caratteri aggiuntivi (80) in quanto comporta anche la trasparenza (0.5) che non è stata prevista nelle altre due funzioni.

A questo punto i codici esadecimali (incluso il doppio apice che li racchiude) possono essere raccolti in tavolozze (palette) da impiegare per applicare automaticamente colori differenti alle diverse componenti di un grafico, come illustrato negli esempi che seguono.

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

# PALETTE (TAVOLOZZE) PERSONALIZZATE
# boxplot differenziati in base a un fattore
#
mydata <- data.frame(xval=1:50, yval=rnorm(50), casi=rep(c("A", "B", "C", "D", "E"), each=10)) # genera i dati di esempio
windows() # apre e inizializza una nuova finestra grafica 
par(mfrow=c(2,2)) # suddivide la finestra grafica in 2 righe per 2 colonne
#
mypalette1 <- c("#F8A19F80", "#90AD1C80", "#F6222E80", "#1CFFCE80", "#2ED9FF80") # tavolozza di colori con trasparenza al 50% 
boxplot(yval~casi, data=mydata, horizontal=FALSE, notch=FALSE, col=mypalette1)  # traccia il boxplot
#
mypalette2 <- c("#AA0DFE80", "#3283FE80", "#85660D80", "#782AB680", "#56565680") # tavolozza di colori con trasparenza al 50% 
boxplot(yval~casi, data=mydata, horizontal=FALSE, notch=FALSE, col=mypalette2)  # traccia il boxplot
#
mypalette3 <- c("#1C8356", "#16FF32", "#F7E1A0", "#E2E2E2", "#1CBE4F") # tavolozza di colori senza trasparenza
boxplot(yval~casi, data=mydata, horizontal=FALSE, notch=FALSE, col=mypalette3) # traccia il boxplot
#
mypalette4 <- c("#C4451C", "#DEA0FD", "#FE00FA", "#325A9B", "#FEAF16") # tavolozza di colori senza trasparenza
boxplot(yval~casi, data=mydata, horizontal=FALSE, notch=FALSE, col=mypalette4)  # traccia il boxplot
#

Come si vede a questo punto diventa semplice predisporre differenti combinazioni di colori e applicarle allo stesso grafico per valutarne preventivamente l'estetica, come nel caso di questo grafico a scatola con i baffi (boxplot).


Ancor più interessante può essere l'applicazione delle stesse combinazioni di colori impiegate qui sopra a un grafico di dispersione (scatterplot) realizzato con ggplot

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

# PALETTE (TAVOLOZZE) PERSONALIZZATE con ggplot
# scatterplot differenziati in base a un fattore
#
library(ggplot2) # carica il pacchetto per la grafica
library(gridExtra) # carica il pacchetto per combinare i grafici in una sola figura
#
mydata <- data.frame(xval=1:50, yval=rnorm(50), casi=rep(c("A", "B", "C", "D", "E"), each=10)) # genera i dati di esempio
windows() # apre e inizializza una nuova finestra grafica
#
mypalette1 <- c("#F8A19F80", "#90AD1C80", "#F6222E80", "#1CFFCE80", "#2ED9FF80") # tavolozza di colori con trasparenza al 50% 
plot1 <- ggplot(mydata, aes(x=xval, y=yval, color=casi)) + geom_point(size=4) +   scale_color_manual(values=mypalette1) + theme_minimal()
#
mypalette2 <- c("#AA0DFE80", "#3283FE80", "#85660D80", "#782AB680", "#56565680") # tavolozza di colori con trasparenza al 50% 
plot2 <- ggplot(mydata, aes(x=xval, y=yval, color=casi)) + geom_point(size=4) + scale_color_manual(values=mypalette2) + theme_minimal()
#
mypalette3 <- c("#1C8356", "#16FF32", "#F7E1A0", "#E2E2E2", "#1CBE4F") # tavolozza di colori senza trasparenza
plot3 <- ggplot(mydata, aes(x=xval, y=yval, color=casi)) + geom_point(size=4) +   scale_color_manual(values=mypalette3) + theme_minimal()
#
mypalette4 <- c("#C4451C", "#DEA0FD", "#FE00FA", "#325A9B", "#FEAF16") # tavolozza di colori senza trasparenza
plot4 <- ggplot(mydata, aes(x=xval, y=yval, color=casi)) + geom_point(size=4) +   scale_color_manual(values=mypalette4) + theme_minimal()
#
# combina i grafici in una sola figura
grid.arrange(plot1, plot2, plot3, plot4, nrow=2, ncol=2)
#

Questo è il risultato, nel quale si può apprezzare come l'impiego di colori possa essere più soddisfacente dell'impiego di simboli, soprattutto nel caso di colori per i quali è stato previsto un effetto di trasparenza, che consente una migliore rappresentazione dei singoli dati quando questi sono molto ravvicinati (vedasi ad esempio il secondo grafico in alto a destra).


Ed ecco un ultimo esempio, un grafico a barre (barplot) realizzato con ggplot che mostra come anche nei grafici di questo tipo i colori possono essere impiegati per identificare i sottoinsiemi identificati da specifici fattori, sempre impiegando le palette precedenti. Copiate e incollate nella Console di R questo script e premete ↵ Invio.

# PALETTE (TAVOLOZZE) PERSONALIZZATE con ggplot
# barplot differenziati in base a un fattore
#
library(ggplot2) # carica il pacchetto per la grafica
library(gridExtra) # carica il pacchetto per combinare i grafici in una sola figura
#
mydata <- data.frame(xval=1:15, yval=rnorm(15), casi=rep(c("A", "B", "C", "D", "E"), each=3)) # genera i dati di esempio
windows() # apre e inizializza una nuova finestra grafica
#
mypalette1 <- c("#F8A19F80", "#90AD1C80", "#F6222E80", "#1CFFCE80", "#2ED9FF80") # tavolozza di colori con trasparenza al 50% 
plot1 <- ggplot(mydata, aes(x=xval, y=yval, color=casi, fill=casi)) + geom_bar(stat="identity") + scale_color_manual(values=mypalette1) + scale_fill_manual(values=mypalette1) + theme_minimal()
#
mypalette2 <- c("#AA0DFE80", "#3283FE80", "#85660D80", "#782AB680", "#56565680") # tavolozza di colori con trasparenza al 50% 
plot2 <- ggplot(mydata, aes(x=xval, y=yval, color=casi, fill=casi)) + geom_bar(stat="identity") + scale_color_manual(values=mypalette2) + scale_fill_manual(values=mypalette2) + theme_minimal()
#
mypalette3 <- c("#1C8356", "#16FF32", "#F7E1A0", "#E2E2E2", "#1CBE4F") # tavolozza di colori senza trasparenza
plot3 <- ggplot(mydata, aes(x=xval, y=yval, color=casi, fill=casi)) + geom_bar(stat="identity") + scale_color_manual(values=mypalette3) + scale_fill_manual(values=mypalette3) + theme_minimal()
#
mypalette4 <- c("#C4451C", "#DEA0FD", "#FE00FA", "#325A9B", "#FEAF16") # tavolozza di colori senza trasparenza
plot4 <- ggplot(mydata, aes(x=xval, y=yval, color=casi, fill=casi)) + geom_bar(stat="identity") + scale_color_manual(values=mypalette4) + scale_fill_manual(values=mypalette4) + theme_minimal()
#
# combina i grafici in una sola figura
grid.arrange(plot1, plot2, plot3, plot4, nrow=2, ncol=2)
#

Questo è il risultato.


Conclusione: la realizzazione di colori personalizzati con le funzioni rgb(), hsv() e hcl() può rappresentare il punto di partenza per la loro combinazione in palette che possono essere salvate e riutilizzate al bisogno per dare un'impronta personale ai propri grafici.


----------


[2] Vedere il post Nomi e codici dei colori di R