2  Introducción a la visualización de datos


Paquetes para este capítulo

Para poder ejecutar en tu ordenador el código de los ejemplos y ejercicios de este capítulo vas a necesitar los paquetes del recuadro siguiente.

Cuando empecemos cada capítulo:

  1. Abre un script de R y guárdalo con el nombre del capítulo: capitulo2.R

  2. Copia las líneas de abajo (click en el icono del cuadro gris de abajo) y pégalas en el script

  3. Ejecútalas: CNTRL + ENTER para ejecutar linea a linea, o CNTRL + ALT + R para ejecutar todo


2.1 R para visualización de datos

ggplot2 es el paquete por excelencia para visualización de datos. Su potencia va asociada a un nivel de complejidad considerable, hasta el punto que hay Cheat sheets oficiales, Cheat sheets buscables, y decenas de miles de preguntas en Stack Overflow.

2.1.1 Primeros pasos - con training wheels

Para empezar a trabajar con ggplot sin tener que preocuparnos de su complejidad, podemos usar la función esquisse::esquisser() del paquete esquisse. Esta nos permite usar la potencia de ggplot para explorar una base de datos de manera muy sencilla.

SOURCE: https://github.com/will-r-chase/blog/blob/master/static/slides/slide_img/esquisse.gif


La manera fácil (1, 2, 3), usando esquisse:


# 1) Asegúrate que hemos instalado el paquete esquisse
  if (!require('esquisse')) install.packages('esquisse'); library('esquisse')

# 2) Lanza el wizard esquisser  
  esquisse::esquisser(iris)

# 3) Crea el gráfico que quieras, exporta el código...

2.1.2 Aprendamos con Garrick

Garrick Aden-Buie ( @grrrck) ha creado una excelente introducción a ggplot2 y la gramática de gráficos. Os recomiendo revisarla para familiarizaros con las funcionalidades de ggplot.

2.2 Visualización de datos con ggplot2

2.2.1 Componentes de una gráfica

En esta sección vamos a ver algunos de los componentes que usaremos cuando visualicemos datos. Muchos de los ejemplos que usaremos vienen de R for data science.

Ingredientes esenciales de una gráfica
  • Aesthetic mappings (aes): Variables, colores, rellenos, formas, …
  • Geoms (geom_): puntos, líneas, boxplots, …
  • Facets (facet_): paneles con diferentes gráficos para cada nivel de una variable categórica, …
  • Transformaciones estadísticas: calcular promedios, barras de error, …

SOURCE: https://skillgaze.com/2017/10/31/understanding-different-visualization-layers-of-ggplot/

2.2.2 Mi primera gráfica en A-B-C

Para crear una gráfica con ggplot, tenemos que:

  • indicar donde están nuestros datos y que mostraremos en los ejes x e y
  • añadir la o las geometrías (geoms) que queramos

Usaremos + para sumar instrucciones, con una lógica de capas superpuestas.

Por ejemplo:

  1. Indicamos los datos y coordenadas: ggplot(data = mpg, aes(x = displ, y = hwy))

  2. Añadimos el geom de puntos para mostrar la relación entre x e y: + geom_point()

  3. Añadimos un segundo geom para trazar una línea de tendencia: + geom_smooth()

El código de la gráfica final sería el siguiente. Si respetamos el orden de las variables, podemos simplificar nuestro código, evitando el data =, x = e y =:


# Los datos están en mpg. Queremos ver la relación entre las variables `displ` y `hwy`
# Usamos geom_point para mostrar puntos 
# Usamos geom_smooth para dibujar linea de tendencia

ggplot(mpg, aes(displ, hwy)) +
  geom_point() + 
  geom_smooth()


2.2.3 Aesthetic mappings

En aes() vamos a indicar las variables que queremos en los ejes x e y, el color de los puntos o líneas, el relleno de las barras, la forma de los puntos, el tipo de linea, la agrupación de los datos, etc.

Parámetros estéticos
  • x: x = gdpPercap
  • y: y = lifeExp
  • color: color = continent; color = “red”; color = “#FAA627”
  • fill: fill = continent; fill = “red”; fill = “#FAA627”
  • alpha: alpha = continent; alpha = 0.2
  • size: size = continent; size = 5
  • shape: shape = continent; shape = 0 ver codigo de las distintas formas
  • linetype: linetype = continent; linetype = “dashed”
  • group: group = continent

Veamos algunos de los parámetros…

2.2.3.1 x-y

Algo esencial es decirle a ggplot qué queremos mostrar en los ejes x e y de nuestra gráfica.

Empezaremos usando los datos de gapminder Vamos a ver qué variables tenemos en el data frame:

Si te aparece el error: Error: object 'gapminder' not found, asegurate de hacer los pasos indicados en el recuadro Paquetes para este capítulo arriba.

gapminder
#> # A tibble: 1,704 × 6
#>   country     continent  year lifeExp      pop gdpPercap
#>   <fct>       <fct>     <int>   <dbl>    <int>     <dbl>
#> 1 Afghanistan Asia       1952    28.8  8425333      779.
#> 2 Afghanistan Asia       1957    30.3  9240934      821.
#> 3 Afghanistan Asia       1962    32.0 10267083      853.
#> 4 Afghanistan Asia       1967    34.0 11537966      836.
#> 5 Afghanistan Asia       1972    36.1 13079460      740.
#> 6 Afghanistan Asia       1977    38.4 14880372      786.
#> # ℹ 1,698 more rows

Visualizamos la relación entre gdpPercap (eje x), y lifeExp (eje y):

ggplot(gapminder, aes(gdpPercap, lifeExp)) + 
  geom_point()

Dentro de aes(), el primer parámetro se refiere al eje x y el segundo al eje y. Si cambiamos el orden del código de arriba, podemos ver de nuevo la relación entre lifeExp y gdpPercap, con los ejes invertidos.


  ggplot(gapminder, aes(lifeExp, gdpPercap)) + 
    geom_point()

Ejercicio

Usando gapminder, ¿podrías crear un gráfico de gdp per cápita por población como éste?

dentro de aes() tenemos que poner gdpPercap y pop

2.2.3.2 Color, alpha, size

Para asignar colores podemos usar nombres de colores en inglés, o algo llamado código HEX:


Empecemos a cambiar parámetros de nuestro gráfico inicial:

  # Gráfico inicial
  ggplot(gapminder, aes(gdpPercap, lifeExp)) + 
    geom_point()

Color “rojo” para los puntos con color = "red".

  ggplot(gapminder, aes(gdpPercap, lifeExp)) + 
    geom_point(color = "red")

Color en función de la variable ‘continent’. Al usar un nombre de variable, tenemos que ponerlo dentro de aes().

continent es una columna de gapminder, no un color. Siempre que usemos nombres de variables, tienen que estar dentro de aes()

  ggplot(gapminder, aes(gdpPercap, lifeExp, color = continent)) + 
    geom_point()

Color en función de la variable ‘continent’. Cambiamos el tamaño de los puntos a 2.

  ggplot(gapminder, aes(gdpPercap, lifeExp, color = continent)) + 
    geom_point(size = .5)

Color en función de la variable ‘continent’. Cambiamos el tamaño de los puntos a 2. Añadimos transparencia usando el parámetro ‘alpha’.

  ggplot(gapminder, aes(gdpPercap, lifeExp, 
                        color = continent,
                        alpha = .1)) + 
    geom_point(size = .5)

Ejercicios

Usando como base el plot siguiente (GDP x población):

ggplot(gapminder, aes(gdpPercap, pop)) + 
    geom_point()

¿Podrías hacer lo siguiente?:

  • Colorear los puntos por continente
  • Tamaño del punto 4
  • Alpha 0.5

Cada uno de los siguientes gráficos tiene un error. ¿Sabrías corregirlos?

ggplot(gapminder, aes(gdpPercap, pop), color = continent) + 
    geom_point(size = 4, alpha = .5)

color = continent debe ir dentro de aes()

ggplot(gapminder, aes(gdpPercap, pop, color = "blue")) + 
    geom_point(size = 4, alpha = .5)

color = “blue” debe ir fuera de aes()


2.2.3.3 Shape

Códigos para las distintas formas

SOURCE: https://r4ds.had.co.nz/data-visualisation.html#aesthetic-mappings

En este ejemplo usamos la variable continent para asignar una forma diferente a cada uno de los continentes.


  ggplot(gapminder, aes(gdpPercap, lifeExp, shape = continent)) + 
    geom_point() 

2.2.3.4 Linetype

Códigos para los distintos estilos de linea

SOURCE: http://sape.inf.usi.ch/quick-reference/ggplot2/linetype

Podemos definir directamente el tipo de línea que queremos en geom_line():


  ggplot(gapminder, aes(year, lifeExp, color = continent)) + 
    stat_summary(fun = mean, geom = "line", linetype = "dashed")

O que el tipo de línea dependa de una variable:


  ggplot(gapminder, aes(year, lifeExp, linetype = continent, color = continent)) + 
    stat_summary(fun = mean, geom = "line") 

2.2.4 Geoms

Una de las cosas más difíciles cuando nos enfrentamos a nuevos datos es elegir el método más efectivo para visualizarlos. Hay varios recursos interesantes sobre cómo elegir una gráfica. Personalmente, para encontrar inspiración, la r graph gallery me parece un recurso fantástico.

En esta sección veremos distintos tipos de geometría, o geoms_().


Algunos tipos de geoms

Para una lista exhaustiva ver el manual de ggplot2.

SOURCE: https://nbisweden.github.io/RaukR-2019/ggplot/presentation/ggplot_presentation_assets/geoms.png

2.2.4.1 geom_point y geom_jitter

Si queremos un gráfico de dispersión o scatterplot, podemos usar el geom_point()

  ggplot(mpg, aes(displ, hwy)) + 
    geom_point()

En algunos casos, tenemos muchos puntos que se superponen. Si usamos geom_jitter() la posición de los puntos cambia levemente de manera aleatoria para evitar superposiciones. Con las propiedades ´width´ y ´height´ podemos controlar el desplazamiento horizontal y vertical máximo.

  ggplot(mpg, aes(displ, hwy)) + 
    geom_jitter()

2.2.4.2 geom_smooth

Podemos añadir líneas de tendencia con geom_smooth(). El method por defecto depende de los datos. Comúnmente se usa loess, pero podemos definir explicitamente el método que queremos (e.g. geom_smooth(method = "lm") para usar una regresión lineal).

Recuerda que las funciones que usamos (todo lo que contiene () e.g. geom_smooth()) tienen parámetros, que son instrucciones adicionales que nos permiten modificar como se comportan. Para ver que opciones tenemos, podemos ver la ayuda de las funciones : ?geom_smooth(), o poner el cursor encima y presionar F1 (ayuda).

  ggplot(gapminder, aes(gdpPercap, lifeExp)) + 
    geom_point() +
    geom_smooth()

Le quitamos el intervalo de confianza con el parámetro se.

  ggplot(gapminder, aes(gdpPercap, lifeExp)) + 
    geom_point() +
    geom_smooth(se = FALSE)

Usamos como método lm. En este caso, por la distribución de los datos, no parece una buena idea…

  ggplot(gapminder, aes(gdpPercap, lifeExp)) + 
    geom_point() +
    geom_smooth(method = "lm")
 

Usamos un color para cada continent. Al indicarlo en el aes() general, esto se aplica a todos los geoms (geometrías).

  ggplot(gapminder, aes(gdpPercap, lifeExp, color = continent)) + 
    geom_point() +
    geom_smooth()
 

Un smooth por cada continente (group = continent). Dado que agrupar los puntos por continente no tiene efecto, solo se ven las múltiples líneas de tendencia.


  ggplot(gapminder, aes(gdpPercap, lifeExp, group = continent)) + 
    geom_point() +
    geom_smooth()
 

Coloreamos puntos pero mantenemos un solo smooth introduciendo el parámetro aes(color = continent) dentro de geom_point(). El lugar donde ponemos aes(color = continent) determina a que geometrías afecta.


  ggplot(gapminder, aes(gdpPercap, lifeExp)) + 
    geom_point(aes(color = continent)) +
    geom_smooth()

    

Ejercicios

Usando como base el siguiente plot:

  ggplot(gapminder, aes(gdpPercap, lifeExp, shape = continent)) + 
    geom_point()
  • Colorea los puntos por continente
  • Muestra una línea de tendencia por continente (sin el intervalo de confianza)
  • Haz que el tipo de línea cambie por continente
  • Añade transparencia a los puntos para que las líneas destaquen

  • parámetro color
  • geom geom_smooth, parámetro se
  • parámetro linetype
  • parámetro alpha dentro de geom_point

Ahora vamos a usar el data frame mpg. Empieza con este plot:


ggplot(mpg, aes(displ, hwy)) + 
  geom_point()

Finalmente, intenta crear los siguientes 6 plots. Te recomiendo avanzar en orden alfabètico.

Para conseguirlo vamos a tener que usar parámetros como group, color o linetype, pensando muy bien si los tenemos que poner en el aes() general, o en un aes() dentro de geoms específicos:

  1. geom geom_smooth, parámetro se
  2. group = drv dentro de aes()
  3. parámetro color dentro del aes() general
  4. parámetro color dentro del geom
  5. parámetro linetype
  6. x2 geom_point

2.2.4.3 geom_boxplot y geom_violin

Podemos crear diagramas de cajas (boxplots) con geom_boxplot o violines con geom_violin para visualizar como cambian los datos por grupo.

Boxplot con relleno (parámetro fill).


  ggplot(gapminder, aes(continent, lifeExp, fill = continent)) + 
    geom_boxplot(alpha = .2)

Los violin plots nos permiten ver la distribución de los datos. Podemos usar el parámetro draw_quantiles para dibujar quantiles, por ejemplo, el percentil 50 (la mediana). Si queremos mostrar los percentiles 25, 50 y 75, tenemos que usar draw_quantiles = c(.25, .5, .75).


  ggplot(gapminder, aes(continent, lifeExp, fill = continent)) + 
    geom_violin(alpha = .2, draw_quantiles = .5)

Podemos combinar geom_violin con geom_jitter para mostrar las observaciones individuales. Si usamos height = 0 y width = .2, los puntos mostraran el valor exacto de lifeExp, y se dispersarán algo en el eje horizontal.


  ggplot(gapminder, aes(continent, lifeExp)) + 
    geom_violin(alpha = .2, aes(fill = continent), draw_quantiles = .5) +
    geom_jitter(alpha = .1, height = 0, width = .2)

2.2.4.4 geom_histogram y geom_bar

Cuando queremos visualizar la distribución de variables continuas, podemos usar histogramas (geom_histogram()). Como puedes ver, ahora solo le pasamos una variable a aes() (el eje y muestra el número de observaciones, y es calculado por ggplot).

  ggplot(gapminder, aes(lifeExp)) + 
    geom_histogram()

Si tenemos variables categóricas, usamos geom_bar(). Podemos usar guides(fill = "none") para que desaparezca la leyenda asociada al color, porque los nombres de cada categoría ya aparecen en el eje x:

  ggplot(gapminder, aes(continent, fill = continent)) +
    geom_bar(alpha = .6) +
    guides(fill = "none")

2.2.4.5 geom_density

Para visualizar distribuciones cuando tenemos muchos datos, podemos usar geom_density(). Eso sí, recuerda que con pocos datos, los gráficos de densidad nos dan una falsa seguridad sobre la forma de nuestra distribución.

  ggplot(gapminder, aes(lifeExp)) + 
      geom_density(alpha = .2, fill = "blue")

Si queremos ver la distribución por continente, usamos el parámetro fill.

Con alpha = .2 podemos añadir transparencia y ver todas las distribuciones. Puedes probar cambiando su valor a 1, para ver que ocurre (alpha puede tener valores de 0 a 1).

  ggplot(gapminder, aes(lifeExp, fill = continent)) + 
      geom_density(alpha = .2)

Ejercicios

En sección geom_boxplot y geom_violin vimos este gráfico:

ggplot(gapminder, aes(continent, lifeExp)) + 
    geom_violin(alpha = .2, aes(fill = continent), draw_quantiles = .5) +
    geom_jitter(alpha = .1, height = 0, width = .2)

Como puedes ver, aes(fill = continent) está en geom_violin(), no en ggplot().

  1. Que pasaría si lo pusieras en la linea ggplot()?
  2. Afecta a los colores de geom_jitter()? ¿Por qué?
  3. ¿Podrias reproducir el gráfico de abajo?

aes(color = continent) debe ir en geom_jitter(). Si se colorean también las lineas de los violines, es que has puesto color = continent dentro de ggplot().

2.2.5 Personalización básica

Una gráfica necesita elementos como el título, ejes con nombres informativos, etc. Usaremos la función labs() para incluir o editar lo siguiente:

  • title: título de la gráfica
  • subtitle: subtítulo
  • caption: pie de gráfica (abajo a la derecha)
  • tag: etiqueta de la gráfica (arriba a la izquierda)
  • x: eje horizontal
  • y: eje vertical
  • fill: título de leyenda si se usa el parámetro fill
  • color: título de leyenda si se usa el parámetro color
  • alt: alt-text, importante para que los lectores de pantalla usados por personas ciegas describan las gráficas

En el siguiente ejemplo, vamos a personalizar la gráfica del ejercicio anterior:

ggplot(gapminder, aes(continent, lifeExp)) + 
  geom_violin(alpha = .2, aes(fill = continent), draw_quantiles = .5) +
  geom_jitter(alpha = .1, height = 0, width = .2, aes(color = continent)) +
  labs(title = "Distribution of life expectancy",
       subtitle = "by continent", 
       caption = "Source, the gapminder dataset",
       tag = "a)",
       x = "Continents",
       y = "Life expectancy (in years)", 
       fill = "Continents",
       color = "Individual countries",
       alt = "Alt text for the plot. Very useful for blind people"
       )

Ejercicio

Usando como base este plot:

   ggplot(mpg, aes(displ, hwy)) + 
    geom_point() +
    geom_smooth(se = FALSE)

Personalízalo añadiendo y modificando:

  • título
  • subtítulo
  • caption
  • ejes x e y

Para conseguir esto:

Con lo que hemos visto en este capítulo, podrás crear una gran cantidad de gráficas. En el siguiente capítulo veremos algunas funcionalidades más avanzadas.

Bibliografía

  • Matejka, J., & Fitzmaurice, G. (2017, May). Same stats, different graphs: Generating datasets with varied appearance and identical statistics through simulated annealing. In Proceedings of the 2017 CHI Conference on Human Factors in Computing Systems (pp. 1290-1294). ACM.

  • https://bbc.github.io/rcookbook/

  • https://github.com/bbc/bbplot

  • https://github.com/dreamRs/esquisse

  • Garrick Aden-Buie. A Gentle Guide to the Grammar of Graphics with ggplot2: https://github.com/gadenbuie/gentle-ggplot2

  • Michael Toth. You Need to Start Branding Your Graphs. Here’s How, with ggplot!: https://michaeltoth.me/you-need-to-start-branding-your-graphs-heres-how-with-ggplot.html

  • Claus Wilke: https://wilkelab.org/practicalgg/

  • Thomas Lin Pedersen:

    • Part 1: https://www.youtube.com/watch?v=h29g21z0a68
    • Part 2: https://www.youtube.com/watch?v=0m4yywqNPVY
  • Big Book or R : https://www.bigbookofr.com/index.html