Tema 01 - Visualización de datos

Pedro Albarrán

Dpto. de Fundamentos del Análisis Económico. Universidad de Alicante

Introducción

  • La representación visual permite resumir información e identificar patrones que no se verían en los datos en bruto (en una hoja de cálculo).

  • En un buen gráfico, la audiencia encuentra obvias las ideas a transmitir, sin abrumar con muchos hallazgos

  • Usaremos la biblioteca ggplot2, basada en la Gramática de Gráficos (Wilkinson, 2005)

    • algunos gráficos simples requieren más opciones que en R base

    • PERO ofrece facilidades para gráficos complejos y profesionales

  • Otras bibliotecas: rgl (gráfics 3D), ggvis (interactivos), plotly

Elementos básicos de un gráfico de datos

  1. Señales visuales: posición, longitud, área, etc.

  2. Sistema de coordenadas: ¿cómo se organizan los puntos de datos?

    • cartesiano, polar, geográfico
  3. Escala: ¿cómo se traduce la distancia en algo con significado?

    • numérica lineal, numérica logarítmica, categórica, de tiempo
  4. Contexto: ¿en relación con qué?

    • títulos, leyendas, etiquetas de ejes, puntos/líneas de referencia
  5. Otros: facetas/pequeños múltiplos, capas, animaciones, etc.

  • “Por encima de todo, mostrar los datos”

Señales Visuales

La “Gramática de Gráficos”

  • Especificar bloques independientes y combinarlos para crear cualquier visualización gráfica, como las frases a partir de nombres, verbos, objetos, etc.

  • Bloques de construcción de un gráfico

    • Datos: data

    • Objeto geométrico (qué dibujamos: líneas, puntos, barras, etc.): geom_*()

    • Atributos estéticos (del objeto geométrico, como posición, color, forma, tamaño) que transmiten información de una variable: aes()

    • Escalas (rango of valores, colores, etc.): scale_*()

    • Sistema de Coordenadas

    • Facetas (pequeños múltiplos): facet_wrap(), facet_grid()

Creando un “ggplot”

ggplot(data = mpg, aes(x = displ, y = hwy)) + 
  geom_point()
ggplot(data = mpg) + 
  geom_point(mapping = aes(x = displ, y = hwy))
  • ggplot(data = mpg) = gráfico vacío (coordenadas cartesianas, por defecto)

  • Añadir capas con +: ej., objeto geométrico del tipo puntos = geom_point()

  • El argumento mapping, asociado a aes(), define cómo las variables son asignadas a propiedades visuales

    • x e y especifican qué variables asignar a cada eje
  • NOTA: el primer código define datos y estética para todas las capas que siguen; el segundo solo para el objeto geométrico de puntos.

Objetos geométricos

  • Cada geom_*() agrega un tipo diferente de capa/marcas en el gráfico

    • puntos (geom_point, para diagramas de dispersión, de puntos, etc.)

    • líneas (geom_line, para series de tiempo, líneas de tendencia, etc.)

    • diagrama de caja (geom_boxplot)

    • etc.

  • Para una lista de objetos geométricos disponibles, buscar las funciones que comienzan con geom_ en la Ayuda

Elementos Estéticos con aes()

  • Elementos estéticos son “algo que se puede ver” (información)

  • Cada elemento estético con aes() es un asociación (“mapping”) entre una señal visual y una variable

    • posición (p.e., en los ejes x e y)
    • color (color “exterior”)
    • relleno (color “interior”), fill
    • forma (de los puntos), shape
    • tipo de línea,
    • tamaño, size
  • Cada geom acepta solo un subconjunto de todos los elementos estéticos.

    • En la ayuda de cada geom se puede ver qué asignaciones acepta en aes().

esquisse: una interfaz gráfica

  • esquisse implementa de forma visual (“arrastrar y soltar”) la lógica de composición de gráficos de ggplot2
  • Ejecutamos esquisser() para crear el gráfico, eligiendo datos
#install.packages("esquisse")
library(esquisse)
esquisser()                         
data("mpg")
esquisser(mpg, viewer = "browser")   # lanzar visor externo   
  • Se pueden elegir muchos (no todos) aspectos del gráfico que veremos en este tema: tipo de gráfico, asignaciones estéticas, títulos, apariencia, etc.

  • Genera un posible código de R para crea el gráfico

  • También se puede descargar el gráfico creado

Gráficos como objetos de R

housing   <- rio::import("data/landdata-states.csv")
hp2001Q1  <- housing[housing$Date == 2001.00,] 
graf_base <- ggplot(hp2001Q1, aes(y = Structure.Cost, x = Land.Value)) +
                geom_point()
  • Se pueden agregar capas a este objeto gráfico y mostrarlo
graf_base + geom_line()        # ¿tiene sentido este gráfico?
graf_base + geom_point(aes(shape = region)) 
  • Añadimos una señal visual de formas (o color, etc.), NO para “embellecer” sino para representar la información de una variable adicional

  • NO saturar el gráfico con estéticas fijas o información innecesaria

graf_base + geom_point(aes(size = Home.Price.Index,   
          color=Home.Value))    # ¿qué aportan estas variables?

Asociación estética y Asignación de opción fija

  • Una asociación (“mapping”) estética, con aes(), visualiza una variable
  • Una opción estética establece, fuera de aes(), un valor fijo de la señal visual
ggplot(hp2001Q1, aes(y = Structure.Cost, x = Land.Value)) +
  geom_point(shape = "cross",  color="red")   
ggplot(hp2001Q1, aes(y = Structure.Cost, x = Land.Value)) +
  geom_point(aes(shape = region, color=Home.Value))

ggplot(hp2001Q1, aes(y = Structure.Cost, x = Land.Value)) +
  geom_point(aes(shape = region, color=Home.Value),
             size = 3)
  • Nota: region, carácter convertido a factor, se representa en escala categórica

Más geoms: “Smoothers” y Texto

  • No todos los geoms son formas simples: aquí, por defecto, una línea (función no lineal estimada) y un área (intervalo de confianza de la predicción)
graf_base + geom_smooth()
graf_base + geom_smooth(method = lm, se = FALSE)  
  • Cada geom acepta un conjunto particular de asignaciones: geom_text() acepta etiquetas
graf_base + geom_text(aes(label=State), size = 3)
  • Si queremos el punto y la etiqueta de texto
#install.packages("ggrepel") 
library(ggrepel)
graf_base + geom_text_repel(aes(label=State), size = 3)

Comentario

  • Cada objeto geométrico puede tener características propias

    • usar datos distintos para diferentes objetos,
    • utilizar diferentes estéticas en distintos objetos, etc..
  • Por ejemplo, usamos solo un subconjunto de los datos para el objeto geométrico de texto

graf_base + geom_point() + 
  geom_text_repel(
    data = subset(hp2001Q1, State %in% c("NY","NJ","KY")), 
    mapping = aes(label=State), size = 3)

Transformaciones Estadísticas

  • En algunos gráficos, como el de dispersión, cada punto grafica unas coordenadas (x e y) iguales al valor original de las variables a representar (aunque podemos transformarlas)
ggplot(hp2001Q1, aes(x = log(Land.Value), y = Structure.Cost)) + 
      geom_point()
  • Otros gráficos representan estadísticas obtenidas a partir de las variables (no las variables directamente)
  • Para “smoother”, se calcula una regresión

  • Para un gráfico de caja, se calculan estadísticos descriptivos

ggplot(hp2001Q1, 
       aes(y = Home.Value/1000)) +  
  geom_boxplot()

Modificar las Transformaciones Estadísticas

  • Podemos cambiar qué estadísticas calcular o representar en geoms que representan estadísticas

  • Un histograma (variables continuas) depende de qué intervalos definamos para calcular las frecuencias: podemos cambiar el número de grupos (bins) o su ancho (binwidth) o fijar los rangos (breaks)

graf <- ggplot(housing, aes(x = Home.Value))
graf + geom_histogram(stat = "bin", binwidth=4000)
graf + geom_histogram(stat = "bin", bins=40)
  • Podemos representar la densidad, en lugar de frecuencias absolutas
graf + geom_histogram(stat = "density" )  
  • En un gráfico de barras (variables discretas), se calculan por defecto frecuencias de una variable, pero podemos representar otra variable, con identity

Escalas: control de la asociación estética

  • aes() establece la variable asignada, no cómo se representa

    • aes(shape = region): qué forma para cada región
    • aes(color = Home.Value): qué color para cada valor
  • Las funciones para modificar la escala siguen el esquema scale_<estética>_<tipo>

  • Argumentos habituales para la escala:

    • name: título de la escala (en eje o leyenda)
    • limits: el mínimo y el máximo de la escala
    • breaks: valores donde deberían aparecer las etiquetas
    • labels: las etiquetas que aparecen en cada break
  • Funciones específicas de escala pueden tener argumentos adicionales

Ejemplos de modificación de escala

g2 <- ggplot(housing, aes(y = State, x = Home.Price.Index)) + 
  geom_point(aes(color = Date))
  • Modificamos breaks, etiquetas y colores de la escala de color
g2 + scale_color_continuous(breaks = c(1975.00, 1994.00, 2013.00),
            labels = c(1975, 1994, 2013), low = "blue", high = "red")
  • Una escala diferente para color, interpolando entre tres colores
g2 + scale_color_gradient2(breaks = c(1975.00, 1994.00, 2013.00),
                           labels = c(1975, 1994, 2013),
                        low = "blue", high = "red", mid = "gray60", 
                        midpoint = 1994.00)

Listado (parcial) de escalas disponibles

Facetas (pequeños múltiplos)

  • Para facilitar la comparación de gráficos (no solo objetos geométricos), se divide en subgráficos para distintos subconjuntos de los datos
graf_estad <- ggplot(housing, aes(x = Date, y = Home.Value))
graf_estad +  geom_line(aes(color = State))        # gráfico confuso
  • facet_wrap() para facetas en función de variable discreta (usando “fórmula”)
graf_estad +  geom_line() + facet_wrap(~State, ncol = 10)
  • facet_grid() para facetas en dos dimensiones
g3 <- ggplot(data = housing %>% filter(Year>2005)) + 
               geom_histogram(aes(x=Home.Value))
g3 +  facet_grid(region ~ Year)

g3 + facet_grid(region ~ .)     # También solo por filas 
g3 + facet_grid(. ~ region)     # o columnas

Contexto con labs(): título, ejes, leyendas

ggplot(hp2001Q1, aes(y = Structure.Cost, x = Land.Value)) +
 geom_point(aes(color = region)) + geom_smooth(method = "lm", se = FALSE) +
 labs(
   title = "Relación entre coste de la construcción y valor del terreno",
   subtitle = "Datos del Primer Trimestre de 2001",
   caption = "Fuente: Elaboración propia")
  • Es una buena idea que los nombres de ejes, leyendas, etc. sean descripciones claras de las variables (y sus unidades)
ggplot(hp2001Q1, aes(y = Structure.Cost/1000, x = Land.Value/1000)) + 
  scale_x_log10() + 
  geom_point(aes(color = region)) + geom_smooth(method = "lm", se = FALSE) +
  labs(x = "Valor del terreno (miles de $), escala logarítmica",
       y = "Valor de la construcción (miles de $)",
       colour = "Región") +
  scale_y_continuous(breaks=seq(80,200,40),labels=seq(80,200,40) )
  • ¿Qué hace la escala logarítmica? ¿Y usar x = log(Land.Value/1000)?

Otros elementos de contexto

  • Ya vimos geom_text() para asociar una variable a un estética de etiqueta

  • annotate() añade objetos geométricos no asociados a variables: “text”, “rect”, “segment”, “pointrange”

ggplot(hp2001Q1, aes(y = Structure.Cost/1000, x = Land.Value/1000)) +
  geom_point(aes(color = region)) + geom_smooth(method = "lm", se = FALSE) +
  scale_x_log10()+
  annotate("text", x = 140, y = 180, label = "casa cara") +
  annotate("text", x = 110, y = 150, label = "R ^ 2 == 0.026", 
           parse = TRUE)
  • Se pueden añadir líneas de referencias verticales, horizontals o diagonales
  g2 +
    geom_vline(aes(xintercept = 1), linetype = 3, color = "black") 

Cambiar colores

  • Se puede cambiar manualmente la combinación (paleta) de colores por defecto dando el nombre o el código hexadecimal HTML de color
graf <- ggplot(hp2001Q1, 
            aes(x = region, y = Home.Value, fill = region)) + 
          geom_boxplot()

graf + scale_fill_manual(
          values = c("red", "green", "blue", "yellow", "gray"))
  • De igual forma se podría cambiar la forma con scale_shape_manual()
  • Es recomendable usar paletas predefinidas, con criterios de diseño y visualización de información, como RColorBrewer o viridis
library(RColorBrewer)
display.brewer.all()
graf + scale_fill_brewer(palette = "Set3")
graf + scale_fill_brewer(palette = "Dark2")

Temas

  • Podemos definir el estilo general del gráfico: etiquetas de los ejes, fondo del gráfico, apariencia de las leyendas, etc.
graf + theme_gray()       # predeterminado
graf + theme_linedraw()
graf + theme_light()
graf + theme_minimal()
graf + theme_dark()
graf + theme_classic()
  • Ciertos elementos específicos del tema pueden ser cambiados con theme() y guardados para definir temas personalizados (para aplicarlos después)
  • ggthemes ofrece temas creados por profesionales en diseño y comunicación
#install.packages("ggthemes")
library(ggthemes)
graf +  theme_economist() +  # diseño gráfico de "The Economist"   
  scale_fill_economist()     

Comentarios finales

  • Guardar los gráficos: en la pestaña , lista desplegable o comando ggsave()
ggsave("my-plot.pdf")
  • Ayuda en RStudio, Help > Cheatsheets > Data Visualization with ggplot2

  • Fuentes de información con chuletas de R y RStudio aquí

    • existen versiones en castellano de algunas de ellas.