Cómo crear 'Warming Stripes' in R

Este año se hicieron muy famosos en todo el mundo los llamados warming stripes, las tiras del calentamiento global, que fueron creadas por el científico Ed Hawkins de la Universidad de Reading. Estos gráficos representan y comunican el cambio climático de una forma muy ilustrativa y eficaz.

A partir de su idea, creé tiras para ejemplos de España, como el siguiente de Madrid.

En este post voy a enseñar cómo se pueden crear estas tiras en R con el paquete ggplot2. Aunque debo decir que existen muchos caminos en R que nos pueden llevar al mismo resultado o a uno similar, incluso dentro de ggplot2.

Datos

En este caso usaremos las temperaturas anuales de Lisboa del GISS Surface Temperature Analysis que comprenden el periodo 1880-2018. Se trata de series temporales homogeneizadas. También se podrían usar temperaturas mensuales u otras series temporales. El archivo se puede descargar aquí. Lo primero que debemos hacer, siempre y cuando no lo hayamos hecho, es instalar la colección de paquetes tidyverse que incluyen también ggplot2. Además, nos hará falta el paquete lubridate para el tratamiento de fechas. Después, importamos los datos de Lisboa que están en formato csv.

#instalamos los paquetes lubridate y tidyverse
if(!require("lubridate")) install.packages("lubridate")
if(!require("tidyverse")) install.packages("tidyverse")

#paquetes
library(tidyverse)
library(lubridate)
library(RColorBrewer)

#importar las temperaturas anuales
temp_lisboa <- read_csv("temp_lisboa.csv")

str(temp_lisboa)
## spec_tbl_df [139 x 18] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ YEAR  : num [1:139] 1880 1881 1882 1883 1884 ...
##  $ JAN   : num [1:139] 9.17 11.37 10.07 10.86 11.16 ...
##  $ FEB   : num [1:139] 12 11.8 11.9 11.5 10.6 ...
##  $ MAR   : num [1:139] 13.6 14.1 13.5 10.5 12.4 ...
##  $ APR   : num [1:139] 13.1 14.4 14 13.8 12.2 ...
##  $ MAY   : num [1:139] 15.7 17.3 15.6 14.6 16.4 ...
##  $ JUN   : num [1:139] 17 19.2 17.9 17.2 19.1 ...
##  $ JUL   : num [1:139] 19.1 21.8 20.3 19.5 21.4 ...
##  $ AUG   : num [1:139] 20.6 23.5 21 21.6 22.4 ...
##  $ SEP   : num [1:139] 20.7 20 18 18.8 19.5 ...
##  $ OCT   : num [1:139] 17.9 16.3 16.4 15.8 16.4 ...
##  $ NOV   : num [1:139] 12.5 14.7 13.7 13.5 12.5 ...
##  $ DEC   : num [1:139] 11.07 9.97 10.66 9.46 10.25 ...
##  $ D-J-F : num [1:139] 10.7 11.4 10.6 11 10.4 ...
##  $ M-A-M : num [1:139] 14.1 15.2 14.3 12.9 13.6 ...
##  $ J-J-A : num [1:139] 18.9 21.5 19.7 19.4 20.9 ...
##  $ S-O-N : num [1:139] 17 17 16 16 16.1 ...
##  $ metANN: num [1:139] 15.2 16.3 15.2 14.8 15.3 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   YEAR = col_double(),
##   ..   JAN = col_double(),
##   ..   FEB = col_double(),
##   ..   MAR = col_double(),
##   ..   APR = col_double(),
##   ..   MAY = col_double(),
##   ..   JUN = col_double(),
##   ..   JUL = col_double(),
##   ..   AUG = col_double(),
##   ..   SEP = col_double(),
##   ..   OCT = col_double(),
##   ..   NOV = col_double(),
##   ..   DEC = col_double(),
##   ..   `D-J-F` = col_double(),
##   ..   `M-A-M` = col_double(),
##   ..   `J-J-A` = col_double(),
##   ..   `S-O-N` = col_double(),
##   ..   metANN = col_double()
##   .. )
##  - attr(*, "problems")=<externalptr>

Vemos en las columnas que tenemos valores mensuales y estacionales, y el valor anual. Pero antes de proceder a visualizar la temperatura anual, debemos sustituir los valores ausentes 999.9 por NA, usando la función ifelse( ) que lleva una condición y los argumentos correspondientes a verdadero y falso de la condición dada.

#selecionamos la columna del año y la temperatura anual
temp_lisboa_yr <- select(temp_lisboa, YEAR, metANN)

#cambiamos el nombre de la columna 
temp_lisboa_yr <- rename(temp_lisboa_yr, ta = metANN)

#valores ausentes 999.9
summary(temp_lisboa_yr) 
##       YEAR            ta        
##  Min.   :1880   Min.   : 14.53  
##  1st Qu.:1914   1st Qu.: 15.65  
##  Median :1949   Median : 16.11  
##  Mean   :1949   Mean   : 37.38  
##  3rd Qu.:1984   3rd Qu.: 16.70  
##  Max.   :2018   Max.   :999.90
temp_lisboa_yr <- mutate(temp_lisboa_yr, ta = ifelse(ta == 999.9, NA, ta))

Cuando usamos el año como variable, no solemos convertirlo en un objeto de fecha, no obstante es aconsejable. De este modo nos permite usar las funciones de fechas del paquete lubridate y las funciones de apoyo dentro de ggplot2. La función str_c( ) del paquete stringr, forma parte de la colección de tidyverse, es similar a paste( ) de R Base que nos permite combinar caracteres especificando un separador (sep=“-”). La función ymd( ) (year month day) del paquete lubridate convierte una fecha en un objeto Date. Es posible combinar varias funciones haciendo uso del pipe operator %>% que ayuda a encadenar sin asignar el resultado a un nuevo objeto. Su uso es muy extendido especialmente con el paquete tidyverse. Si quieres saber más de su uso, aquí tienes un tutorial.

temp_lisboa_yr <- mutate(temp_lisboa_yr, date = str_c(YEAR, "01-01", sep = "-") %>% ymd())

Creando las tiras

Primero, creamos el estilo del gráfico, especificando todo los argumentos del aspecto que queremos ajustar. Partimos del estilo por defecto de theme_minimal( ). Además, asignamos los colores procedientes de RColorBrewer a un objeto col_srip. Más información sobre los colores usados aquí.

theme_strip <- theme_minimal()+
                 theme(axis.text.y = element_blank(),
                       axis.line.y = element_blank(),
                       axis.title = element_blank(),
                       panel.grid.major = element_blank(),
                       legend.title = element_blank(),
                       axis.text.x = element_text(vjust = 3),
                       panel.grid.minor = element_blank(),
                       plot.title = element_text(size = 14, face = "bold")
                       )


col_strip <- brewer.pal(11, "RdBu")

brewer.pal.info
##          maxcolors category colorblind
## BrBG            11      div       TRUE
## PiYG            11      div       TRUE
## PRGn            11      div       TRUE
## PuOr            11      div       TRUE
## RdBu            11      div       TRUE
## RdGy            11      div      FALSE
## RdYlBu          11      div       TRUE
## RdYlGn          11      div      FALSE
## Spectral        11      div      FALSE
## Accent           8     qual      FALSE
## Dark2            8     qual       TRUE
## Paired          12     qual       TRUE
## Pastel1          9     qual      FALSE
## Pastel2          8     qual      FALSE
## Set1             9     qual      FALSE
## Set2             8     qual       TRUE
## Set3            12     qual      FALSE
## Blues            9      seq       TRUE
## BuGn             9      seq       TRUE
## BuPu             9      seq       TRUE
## GnBu             9      seq       TRUE
## Greens           9      seq       TRUE
## Greys            9      seq       TRUE
## Oranges          9      seq       TRUE
## OrRd             9      seq       TRUE
## PuBu             9      seq       TRUE
## PuBuGn           9      seq       TRUE
## PuRd             9      seq       TRUE
## Purples          9      seq       TRUE
## RdPu             9      seq       TRUE
## Reds             9      seq       TRUE
## YlGn             9      seq       TRUE
## YlGnBu           9      seq       TRUE
## YlOrBr           9      seq       TRUE
## YlOrRd           9      seq       TRUE

Para el gráfico final usamos la geometría geom_tile( ). Como los datos no tienen un valor específico para el eje Y, usamos un valor dummy, aquí es 1. Además, ajusto el ancho de la barra de colores en la leyenda.

     ggplot(temp_lisboa_yr,
             aes(x = date, y = 1,fill = ta))+
        geom_tile()+
           scale_x_date(date_breaks = "6 years",
                     date_labels = "%Y",
                     expand = c(0, 0))+
           scale_y_continuous(expand = c(0, 0))+
           scale_fill_gradientn(colors = rev(col_strip))+
           guides(fill = guide_colorbar(barwidth = 1))+
           labs(title = "LISBOA 1880-2018",
                caption = "Datos: GISS Surface Temperature Analysis")+
             theme_strip

En el caso de que quisieramos obtener únicamente las tiras, podemos usar theme_void( ) y el argumento show.legend=FALSE en geom_tile( ) para eliminar todos los elementos de estilo. También podemos cambiar el color para los valores NA, incluyendo el argumento na.value=“grey70” en la función scale_fill_gradientn( ).

     ggplot(temp_lisboa_yr,
             aes(x = date, y = 1, fill = ta))+
        geom_tile(show.legend = FALSE)+
           scale_x_date(date_breaks = "6 years",
                     date_labels = "%Y",
                     expand = c(0, 0))+
           scale_y_discrete(expand = c(0, 0))+
           scale_fill_gradientn(colors = rev(col_strip))+
             theme_void()

Buy Me A Coffee

Dr. Dominic Royé
Dr. Dominic Royé
Investigador y responsable de ciencia de datos

Relacionado