Introducción

La librería ggplot2 de R es un sistema organizado de visualización de datos. Forma parte del conjunto de librerías llamado tidyverse. En este documento se introduce su uso, principalmente a través de ejemplos. La primera parte muestra las características generales del sistema utilizando como ejemplo los diagramas de dispersión. En la segunda parte se detalla cómo representar algunos de los gráficos más conocidos.

Los elementos necesarios para representar un gráfico con ggplot2son los siguientes:

  • Un data frame que contiene los datos que se quieren visualizar.
  • Los aesthetics, es decir, una lista de relaciones entre las variables del fichero de datos y determinados aspectos del gráfico (como por ejemplo coordenadas, formas o colores).
  • Los geoms, que especifican los elementos geométricos (puntos, líneas, círculos, etc) que se van a representar.

Normalmente estos elementos se van añadiendo de forma consecutiva en distintas capas (layers). Para añadir una nueva capa se usa el signo +. La estructura general del código para obtener un gráfico es esta:

ggplot(data = 'nombre del fichero de datos') +
  geom_nombre1(aes(aesthetics1=var1, aesthetics2=var2, ...)) +
  geom_nombre2(...) 

El comando ggplotse usa para generar el sistema de coordenadas (por defecto, rectangulares) y posteriormente vamos añadiendo los geoms con sus correspondientes aesthetics. En principio los aesthetics se pueden asignar individualmente para cada geom.

Primera parte: un ejemplo (diagramas de dispersión)

Los datos

Utilizamos el fichero notas que contiene las notas medias en 1000 colegios de una prueba de nivel que realizó la Comunidad de Madrid en 2009 y 2010, junto con el tipo de colegio (concertado, privado o público). Lo primero, cargamos ggplot2 y leemos los datos:

library(tidyverse)
notas <- read.table('http://verso.mat.uam.es/~joser.berrendero/datos/notas.txt',
                   sep = ' ',
                   dec = ',',
                   header=TRUE)
head(notas)
##         tipo nota09 nota10
## 1 concertado   9.34  8.520
## 2    publico   9.24  5.960
## 3 concertado   9.17  5.460
## 4    privado   9.14  7.925
## 5    publico   9.09  6.400
## 6    publico   9.06  7.940

Crear un gráfico y añadir capas

Para crear un gráfico se usa el comando ggplot:

ggplot(data = notas)

De momento solo hemos asignado al gráfico el conjunto de datos que queremos visualizar. No se representa gráficamente nada hasta que no se añaden más capas. Importante: los datos a representar siempre tienen que formar parte de un data frame.

Las capas sirven para proporcionar información sobre cómo queremos visualizar los datos. Esto se lleva a cabo a través de un geom. Este es un ejemplo sencillo usando geom_point que es el geomcorrespondiente un diagrama de dispersión (cada tipo de gráfico tiene el suyo). En primer lugar, mediante aes asignamos las coordenadas x e y a los valores de las notas de 2009 y 2010 respectivamente.

ggplot(data = notas) +
  geom_point(aes(x = nota09, y = nota10))

Si queremos añadir información sobre el tipo de colegio, lo podemos hacer especificando que el color con el que se representa el punto dependa de la variable tipo:

ggplot(data = notas) +
  geom_point(aes(x = nota09, y = nota10, col = tipo))

Vemos como el argumento aes (que corresponde a aesthetics) asigna variables a ciertos aspectos del gráfico. Estos aspectos se pueden fijar en lugar de hacerlos depender de una variable. En este caso el valor del argumento se asigna fuera de la lista de aesthetics. En el siguiente ejemplo se ha fijado el color de los puntos, su tamaño y el grado de transparencia (lo que es útil cuando hay muchos puntos):

ggplot(data = notas) +
  geom_point(aes(x = nota09, y = nota10),
                     col = 'darkblue',    # color de los puntos
                     size = 3,            # tamaño de los puntos
                     alpha = 1/5)         # nivel de transparencia de los puntos 

En general, cada geom admitirá un conjunto determinado de aesthetics. En el caso particular de geom_point, mediante aes podemos hacer depender de una variable otros aspectos como la forma o el tamaño de los puntos:

ggplot(data = notas) +
  geom_point(aes(x = nota09, y = nota10, shape= tipo))   # una forma para cada tipo de colegio

Es necesario consultar la página de ggplot2 para saber qué aesthetics admite cada geomen particular.

Transformaciones estadísticas

Algunos geoms requieren llevar a cabo alguna transformación estadística (técnicamente, un stat) que toma un conjunto de datos y crea otro nuevo. De esta forma combinando geom y stat se pueden obtener una gran variedad de visualizaciones. A veces se puede asignar una transformación estadística a un geom mediante el argumento method. Por ejemplo, geom_smooth usa distintos métodos para estimar la media condicionada (curva de regresión) de una variable por otra, incluyendo el método de mínimos cuadrados, que es el más conocido:

ggplot(data = notas) +
  geom_point(aes(x = nota09, y = nota10),
                     col = 'darkblue',
                     size = 3,
                     alpha = 1/5) + 
  geom_smooth(aes(x = nota09, y = nota10), method = 'lm')    # Añade la recta de mínimos cuadrados
## `geom_smooth()` using formula 'y ~ x'

La opción por defecto no es la recta de mínimos cuadrados, sino un método de suavizado no paramétrico:

ggplot(data = notas) +
  geom_point(aes(x = nota09, y = nota10),
                     col = 'darkblue',
                     size = 3,
                     alpha = 1/5) + 
  geom_smooth(aes(x = nota09, y = nota10))    # Opción por defecto
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'

La asignación de las coordenadas x e y a las variables podría también haberse hecho de una vez en la primera línea (pero el código anterior tiene la ventaja de que permite hacer una asignación a variables diferentes en cada geom en vez de mantener la asignación fija para todos ellos):

ggplot(data = notas, aes(x = nota09, y = nota10)) +     # Esta asignación se fija para todos los geoms 
  geom_point(col = 'darkblue', size = 3, alpha = 1/5) + 
  geom_smooth(method = 'lm')
## `geom_smooth()` using formula 'y ~ x'

Vemos que se representan unas bandas de confianza. En el siguiente ejemplo las eliminamos y, además, modificamos otros aspectos estéticos del gráfico:

ggplot(data = notas) +
  geom_point(aes(x = nota09, y = nota10),
                     col = 'darkblue',
                     size = 3,
                     alpha = 1/5) + 
  geom_smooth(aes(x = nota09, y = nota10),
              method = 'lm',
              col = 'black',    # Se representa la recta en color negro
              se=FALSE)         # Se eliminan las bandas de confianza (se=standard error)
## `geom_smooth()` using formula 'y ~ x'

Si asignamos el tipo de línea al tipo de colegio, obtendremos las rectas de mínimos cuadrados para los tres tipos de colegios:

ggplot(data = notas) +
  geom_point(aes(x = nota09, y = nota10),
                     col = 'darkblue',
                     size = 3,
                     alpha = 1/5) + 
  geom_smooth(aes(x = nota09, y = nota10, linetype = tipo),     # calcula una recta para cada tipo
              method = 'lm',
              col = 'black',
              se=FALSE)
## `geom_smooth()` using formula 'y ~ x'

Gráficos condicionados a los valores de una variable

Puede ser conveniente representar un gráfico para cada uno de los tipos de colegio por separado. Los facets, otro elemento importante en ggplot2, determinan que se debe representar un gráfico condicionado a cada uno de los valores de alguna de las variables. Se añaden de la siguiente forma:

ggplot(data = notas) +
  geom_point(aes(x = nota09, y = nota10),
                     col = 'darkblue',
                     size = 3,
                     alpha = 1/5) + 
  geom_smooth(aes(x = nota09, y = nota10),
              method = 'lm',
              col = 'black',
              se=FALSE) + 
  facet_wrap( ~ tipo)       # un gráfico para cada tipo de colegio
## `geom_smooth()` using formula 'y ~ x'

Como se puede ver, el argumento de facet_wrap utiliza una fórmula análoga a las utilizadas en general para ajustar modelos con R. Compara el ejemplo anterior con el siguiente:

ggplot(data = notas) +
  geom_point(aes(x = nota09, y = nota10),
                     col = 'darkblue',
                     size = 3,
                     alpha = 1/5) + 
  geom_smooth(aes(x = nota09, y = nota10),
              method = 'lm',
              col = 'black',
              se=FALSE) +
  facet_wrap( ~ tipo, nrow = 3)
## `geom_smooth()` using formula 'y ~ x'

Títulos y etiquetas en los ejes

Podemos añadir un título o cambiar las etiquetas de los ejes añadiendo una nueva capa con el comando labs:

ggplot(data = notas) +
  geom_point(aes(x = nota09, y = nota10),
                     col = 'darkblue',
                     size = 3,
                     alpha = 1/5) + 
  geom_smooth(aes(x = nota09, y = nota10),
              method = 'lm',
              col = 'black',
              se=FALSE) + 
  facet_wrap(~tipo) +
  labs(title='Notas de 2010 en función de notas de 2009',
       x='Nota de 2009',
       y='Nota de 2010')
## `geom_smooth()` using formula 'y ~ x'

Otros estilos de gráficos

Hemos usado el estilo de gráficos por defecto con su característico fondo gris que no gusta a todo el mundo. Se puede cambiar añadiendo una nueva capa. En el siguiente ejemplo usamos theme_minimal(). También hemos usado un argumento opcional que cambia el tipo de letra.

ggplot(data = notas) +
  geom_point(aes(x = nota09, y = nota10),
                     col = 'darkblue',
                     size = 3,
                     alpha = 1/5) + 
  geom_smooth(aes(x = nota09, y = nota10),
              method = 'lm',
              col = 'black',
              se=FALSE) + 
  facet_wrap(~ tipo) +
  labs(title='Notas de 2010 en función de notas de 2009',
       x='Nota de 2009',
       y='Nota de 2010') +
  theme_minimal(base_family="mono")      # base_family es un argumento (opcional) para cambiar el tipo de letra
## `geom_smooth()` using formula 'y ~ x'

Hay muchos otros temas que se pueden usar y personalizar.

Segunda parte: principales tipos de gráficos

Una vez que hemos visto los principios básicos del sistema, comentaremos algunos ejemplos de los tipos de gráficos más utilizados: líneas, diagramas de barras, histogramas y diagramas de cajas.

Líneas

Tal vez el gráfico más básico consiste en representar una línea, que permite visualizar una serie temporal o cualquier función matemática. En ggplot2 añadimos una capa con el comando geom_line. En el siguiente ejemplo se representan las funciones seno y coseno en el intervalo \([-\pi,\pi]\).

x <- seq(-2*pi, 2*pi, 0.01)  
datos <- data.frame(x = x, y = sin(x), z = cos(x))  # se crea el data frame con los datos
ggplot(datos) +
  geom_line(aes(x=x, y=y)) +
  geom_line(aes(x=x, y=z), linetype=2, size=2)      # para el coseno línea discontinua con grosor doble

Diagramas de barras

Se usa geom_bar. La operación estadística por defecto (el statque se usa implícitamente) es calcular las frecuencias de cada uno de los valores de la variable que se asigna a x. En comparación con los ejemplos anteriores, basta especificar la coordenada x en lugar de la xy la y, ya que la variable asignada a y por defecto son las frecuencias.

Veamos dos ejemplos, el primero con todas las opciones por defecto y el segundo con el aspecto modificado.

# Opción por defecto 
ggplot(data = notas) +
  geom_bar(aes(x = tipo))

# Algunos parámetros modificados
ggplot(data = notas) +
  geom_bar(aes(x = tipo),
           width=0.3,
           fill='tomato2') +
  theme_classic()

Si disponemos ya del vector de frecuencias, hay que cambiar varios detalles del código anterior. Supongamos que hay tres grupos A, B y C con frecuencias 20, 20 y 60 respectivamente. En este caso hay que asignar la variable del eje \(x\) y también la del eje \(y\). Además, hay que cambiar el stat por defecto (recordamos que este es contar el número de observaciones de cada valor). El nuevo states identity que consiste en dejar la variable asignada a y (es decir, las frecuencias) tal y como está sin modificar nada.

datos_frecuencias <- data.frame(grupo = c('A','B','C'), frecuencias = c(20, 20, 60))
ggplot(data = datos_frecuencias) + 
  geom_bar(aes(x = grupo, y = frecuencias),
           stat = 'identity',
           width = 0.3,
           fill='tomato2')  +
  theme_classic()# el argumento stat modifica la opción por defecto

Histogramas

Para representar un histograma se usa geom_histogram. Con las opciones por defecto resulta:

ggplot(data = notas) +
  geom_histogram(aes(x = nota09))
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Con el siguiente código cambiamos el número de rectángulos del histograma, los colores y otros aspectos del gráfico:

ggplot(notas) +
  geom_histogram(aes(x = nota09,
                     y=..density..),  # para que el área sea 1
                 bins=10,
                 fill='lightblue',
                 col='black') +
  labs(x = 'Notas de 2009', y = 'Frecuencias', title = 'Histograma') +
  facet_wrap( ~ tipo, nrow = 3) +
  theme_minimal() +  
  theme(panel.grid = element_blank())  # elimina grid de fondo

Diagramas de cajas

Para representar diagramas de cajas se usa geom_boxplot.

ggplot(notas) +
  geom_boxplot(aes(x = tipo, y = nota09 ))

Para cambiar los ejes se usa coord_flip. Es posible añadir los puntos con geom_jitter:

ggplot(notas) +
  geom_boxplot(aes(x = tipo, y = nota09)) + 
  coord_flip() +
  geom_jitter(aes(x = tipo, y = nota09), 
              size = 2,
              alpha = 0.1,
              width = 0.1)