Galería de gráficos ggplot2:

Introducción

Vamos a trabajar diferentes tipos de gráficos y algunas de sus opciones. Así, esta sección es una muestra de los gráficos más usuales y cómo abordarlos con ggplot de forma rápida. Para ahondar en cada uno de los tipos debe de estudiarse bien cómo se comportan los diferentes elementos, aesthetics , layers geométricos y otros en cada tipo de gráfico específico. Generalmente, algunos tipos de atributos estéticos trabajan mejor con ciertos tipos de variables, por ejemplo color y shape son apropiados para variables categóricas, size con continuas.

Gráficos de puntos

Lo más directo para hacer un gráfico de dispersión de puntos o Stripchart sería pensar en geom_points():

e <- ggplot(ToothGrowth, aes(x = dose, y = len))
e + geom_point()

Pero es más vistoso, o apropiado, emplear la función geom_jitter()que introduce un poco de ruido a los puntos de cada categoría y nos permite ver la densidad de puntos en cada categoría ya que se superponen menos, o es esperable que menos, que sin jitter.

e + geom_jitter()

La función geom_jitter() admite varios parámetros, como el grado de la fluctuación (o jitter) en horizontal y aesthetics clásicos como shape, size,...

Intenta ampliar la fluctuación/jitter, empleando position=position_jitter(...) en el argumento de geom_jitter(). Cambia la forma de los puntos en el gráfico anterior:

e + geom_jitter(position=...., shape=...)
e + geom_jitter(position=position_jitter(0.2), shape=17)
¿Puedes hacer que cada dosis tenga una forma de punto diferente?
e + geom_jitter(.....)
e + geom_jitter( aes( shape=factor(dose) ) )

Como la función jitter introduce una "variabilidad aleatoria", cada vez que la ejecutemos nos saldrá diferente la nube de puntos. En ocasiones conviene fijar la semilla de aleatoriedad con set.seed(). Ejecuta varias veces las siguientes sentencias con y sin set.seed() (coméntala en su caso).

set.seed(pi)
e + geom_jitter()

Stats

Podemos emplear la función stat_summary() para incluir "cálculos estadísticos" como la media o mediana en un gráfico que lo admita, por ejemplo boxplots, Stripcharts, violines,...

e <- ggplot(ToothGrowth, aes(x = dose, y = len))
e + geom_jitter(position = position_jitter(0.2)) +
    stat_summary(fun.y = mean, geom = "point"
                 , shape = 18, size = 3, color = "red")

La función, o layer stat_summary() tiene muchos argumentos interesantes, podemos explorarlos con la ayuda de R. Presiona F1 sobre stat_summary() o ejecuta la siguiente sentencia:

?stat_summary

La función fun.data devuelve los extremos de un segmento y permite dibujar intervalos.

e + geom_jitter(position = position_jitter(0.2)) +
    stat_summary(fun.data="mean_se", fun.args = list(mult=1)
                 , geom="pointrange", color = "red")

¿Cómo representarías un intervalo de confianza al 95%?

e + geom_jitter(position = position_jitter(0.2)) +
    stat_summary(fun.data="mean_se", fun.args = list(mult=1)
                 , geom="pointrange", color = "red")
z_alfa/2 para la normal es muy próximo a 1.96. modifica la lista de argumentos de `fun.data` en `fun.args`.

Ejercicio: ¿Se te ocurre alguna manera de que aparecieran las tres dosis distribuidas uniformemente en el eje OX (igual distancia)?

e <- ggplot(ToothGrowth, aes(x = factor(ToothGrowth$dose), y = len))
e + geom_jitter(position = position_jitter(0.2)) +
    stat_summary(fun.y = mean, geom = "point"
                 , shape = 18, size = 3, color = "red")
Prueba en el "mapeado" de los datos en aes() a pasar la variable dosis a factor: 
x = factor(ToothGrowth$dose)

Puntos, Boxplots y Violines

Si introducimos una variable categórica o no numérica en la llamada a aes() estamos definiendo un esquema propicio para realizar representaciones gráficas por esa "categoría".

class(mpg$drv); class(mpg$hwy)
## [1] "character"
## [1] "integer"
ggplot( data = mpg, aes(drv, hwy) ) +
    geom_point()

Cambiamos el layer geom_point() por geom_boxplot() para obtener un boxplot.

ggplot( data = mpg, aes(drv, hwy) ) +
    geom_boxplot()

Podemos refinar un boxplot añadiendo colores o formas diversas a los valores atípicos, haciendo que su anchura sea proporcional al tamaño del grupo, etc...

ggplot( data = mpg, aes(drv, hwy) ) +
    geom_boxplot() +
    stat_boxplot(outlier.colour ="red"
                 , varwidth=TRUE, notch=TRUE, notchwidth=0.7
                 , coef = 2)

Gráficas de violines

Con geom_violin() obtenemos gráficas de violines.

ggplot( data = mpg, aes(drv, hwy) ) +
    geom_violin()
ggplot( data = mpg, aes(drv, hwy) ) +
    geom_violin() + geom_point() + geom_jitter()

Añade al gráfico anterior un rombo para representar la media de cada drv:

ggplot( data = mpg, aes(drv, hwy) ) +
    geom_violin() + geom_point() + geom_jitter() +
    stat_summary(......)
ggplot( data = mpg, aes(drv, hwy) ) +
    geom_violin() + geom_point() + geom_jitter() +
    stat_summary(fun.y = mean, geom = "point", shape = 18, size = 5, color = "red")

xkcd

Suavizado: Smoother

Si tenemos un diagrama de puntos con mucho ruido es en ocasiones complicado ver la forma predominante así que puede ser interesante añadir una linea suavizada de tendencia con geom_smooth().

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

Jugando con los argumentos de ´geom_smoth()´ podemos decidir si queremos el área de confianza que aparece en gris (se=TRUE) o el método por defecto fijado en loess (otros: gam, lm, rlm), la amplitud del suavizado con span (varía entre 0 y 1). Prueba diferentes valores y observa la diferencia:

ggplot( data = mpg, aes(displ, hwy) ) +
    geom_point() +
    geom_smooth(span=0.2, method = "loess")

Histogramas

Para crear un histograma o un polígono de frecuencias no necesitamos dos variables en aes(), y emplearemos los layeres: geom_histogram() y geom_freqpoly()

ggplot( data = mpg, aes(hwy) ) +
    geom_histogram() 
ggplot( data = mpg, aes(hwy) ) +
    geom_freqpoly() 

En ambos casos para refinar, tenemos que pensar en cómo agrupar los datos y modificar el argumento binwidth (anchura de las barras) o el argumentos bins (numero de barras) que por defecto es 30 (solo uno de los dos pues el primero sobre escribe al segundo).

ggplot( data = mpg, aes(hwy) ) +
    geom_histogram(bins=15) 

Podemos tunearlo con más argumentos de geom_histogram()

ggplot( data = mpg, aes(hwy) ) +
    geom_histogram(color = "black", fill = "gray", bins=32)

Tanto los histogramas como los polígonos de frecuencias son muy parecidos y así lo son los argumentos que admiten, puedes probarlo haciendo uso de la ayuda. Los polígonos de frecuencia suelen ser más adecuados cuando se desea comparar la distribución entre los niveles de una variable categórica.

?geom_histogram()

Gráficos de densidad

Un gráfico de densidad muestra la distribución de datos de una variable en un intervalo continuo.

ggplot( data = mpg, aes(displ) ) +
    geom_density()

y si queremos comparar las distribuciones según drv:

ggplot( data = mpg, aes(displ, color=drv) ) +
    geom_density()

Para comparar densidades también podríamos emplear geom_grid()

ggplot( data = mpg, aes(displ ) ) +
    geom_density()+
    facet_grid(...)
ggplot( data = mpg, aes(displ ) ) +
    geom_density()+
    facet_grid(drv~.)

Diagramas de barras

Partimos de un nuevo conjunto de datos

df <- data.frame(droga=c("a", "b", "c"),
                 efecto=c(4.2,6.1, 9.7))
head(df)

Ahora hemos de especificar a geom_bar() que no emplee el estadístico por defecto que agrupa los datos con stat = "identity", por defecto usará stat = "count":

ggplot( data = df, aes(droga, efecto) ) +
    geom_bar(stat = "identity")

Cuando queremos que sí haga el conteo no hay que especificar nada en el argumento stat. Veamos qué ocurre con el conjunto de datos mpg y la variable no numérica mpg$fl:

class(mpg$fl)
## [1] "character"
ggplot(mpg, aes(fl)) +
    geom_bar()

Barras apiladas

df1 <- data.frame(hosp=rep(c("H1", "H2"), each=3),
                   droga=rep(c("a", "b", "c"), 2),
                   efecto=c(6.2, 8.1, 11.7, 4.2,6.1, 9.7) )
head(df1)
ggplot( data = df1, aes(droga, efecto, fill=hosp) ) +
    geom_bar(stat = "identity") 

Observad cómo hemos rellenado las barras según el color de hosp.

Por defecto, múltiples barras que ocupan la misma posición x serán apiladas una encima de otra (position_stack()). Si queremos que se sitúen de lado a lado, usamos position_dodge() o position_dodge2(). position_fill() muestra las proporciones relativas en cada x apilando las barras y estandarizando cada barra para que tenga la misma altura.

Prueba a cambiar position_dodge() por position_dodge2():
ggplot( data = df1, aes(droga, efecto, fill=hosp) ) +
    geom_bar(stat = "identity", position = position_dodge())

Gráficos de líneas

df
ggplot( data = df, aes(droga, efecto, group=1) ) +
    geom_line() +
    geom_point()

Con agrupaciones

df2 <- data.frame( grupo=rep(c("g1", "g2"), each=3),
                   dosis=rep(c("0.5", "1", "2"),2),
                   efecto=c(6.8, 15, 33, 4.2, 10, 29.5)
                   )
head(df2)
ggplot( data = df2, aes(dosis, efecto, group=grupo) ) +
    geom_line(aes(linetype=grupo, color=grupo)) +
    geom_point(aes(shape=grupo, color=grupo))

Atención al tratamiento que hacemos del eje OX dependiendo de si es una variable numérica o no.

df2$dosis <- as.numeric(df2$dosis)

ggplot(data=df2, aes(x = dosis, y = efecto, group = grupo, color = grupo)) +
    geom_line() +
    geom_point()

frente a esto:

df2$dosis <- factor(df2$dosis)

ggplot(data=df2, aes(x = dosis, y = efecto, group = grupo, color = grupo)) +
    geom_line() +
    geom_point()

Gráficos de errores

xkcd error bars

Si queremos un gráfico de errores o intervalos de confianza tenemos varias opciones:

  • geom_crosssbar(): parecido a un boxplot sin bigotes, una barra indica el centro
  • geom_errorbar(): barras de error
  • geom_errorbarh(): barras de error horizontales
  • geom_linerange(): una línea vertical representa el intervalo
  • geom_pointrange(): una línea vertical representa el intervalo con un punto en el centro.

Tenemos que especificar a ggplot cual será el centro y la amplitud a ambos lados del centro (simétrico). Para eso hacemos uso de un dataframe intermedio que calculamos, por ejemplo con dplyr, de la siguiente manera:

df4      <- ToothGrowth
df4$dose <- as.factor(df4$dose)
head(df4)
library("dplyr")
df4a <- df4 %>%
    group_by(dose) %>%
    summarise(
        sd = sd(len),
        len = mean(len)
    )
head(df4a)

df4a tiene toda la información que necesitamos, especificamos en aes() los centros y amplitudes:

f <- ggplot(df4a, aes(x = dose, y = len, ymin = len-sd, ymax = len+sd))
f + geom_errorbar()
f + geom_pointrange()

Gráficos de barras y líneas con barras de error

Para el clásico, y mal usado, gráfico de barras y errores que tanto nos recuerda a los detonadores marca ACME, combinaremos dos layers: geom_bar() y geom_errorbar()

f <- ggplot(df4a, aes(x = dose, y = len, ymin = len-sd, ymax = len+sd))

f + geom_bar(aes(color = dose), stat = "identity", fill ="white") +
    geom_errorbar(aes(color = dose), width = 0.2)

cat("Solo las barras en la parte superior:")
f + geom_bar(aes(color = dose), stat="identity", fill ="white") +
    geom_errorbar(aes(color = dose, ymin = len), width=.2)

Para el de líneas se hace de manera similar:

ggplot(df4a, aes(x = dose, y = len, ymin = len-sd, ymax = len+sd)) +
    geom_line(aes(group = 1)) + geom_errorbar(width = 0.2)

Nota: group=1 es una agrupación "dummy" para anular el comportamiento por defecto, que aquí sería agrupar por dose y en general es agrupar por la variable x.

Multiples grupos y barras de error

Ahora necesitaremos dos variables categóricas: una que especifique los grupos del eje OX y otra adicional que es la que queremos mostrar. Transformamos el conjunto de datos df4 de la siguiente manera con dplyr.

library("dplyr")
df4a2 <- df4 %>%
    group_by(dose,supp) %>%
    summarise(
        sd = sd(len),
        len = mean(len)
    )
df4a2

Basta ahora especificar en aes() el agrupamiento

f <- ggplot(df4a2, aes(x = dose, y = len, ymin = len-sd, ymax = len+sd) )

f + geom_crossbar(  aes(color = supp) )
f + geom_crossbar(  aes(color = supp), position = position_dodge(1) )
f + geom_pointrange(aes(color = supp), position = position_dodge(1) )

Si lo que queremos son detonadores ACME o líneas:

f + geom_bar(aes(fill = supp), stat = "identity", position = "dodge") +
    geom_errorbar(aes(color = supp), position = "dodge")

f + geom_line(    aes(group = supp, color = supp) ) +
    geom_point(   aes(color = supp) )+
    geom_errorbar(aes(color = supp), width=.2,position = position_dodge(0.05) )

Autoevaluación

Practica lo que has aprendido descargando el siguiente fichero Rmd, abriéndolo con Rstudio y resolviendo las preguntas de autoevaluación.

Autoevaluación

Para descargar el Rmd de autoevaluación haz click derecho en el enlace anterior y "Guardar enlace como..." y selecciona dónde quieres guardarlo.

Si al abrirlo con Rstudio observas caracteres extraños, selecciona File/Reopen with encoding/UTF-8 y ya se debe ver bien.

Dónde seguir

  • STHDA Statistical tools for high-throughput data analysis. Web interesante con lo esencial de ggplot2

  • El libro de Winston Chang Cookbook for R es un manual magnífico de fácil y rápido acceso.

    Un gráfico más que mis palabras

  • “C’est le temps que tu as perdu pour ta rose qui fait ta rose si importante” (Antoine de Saint-Exupery, Le Petit Prince). Librería esquisse. Esta librería incluye una variedad de utilidades para explorar y extraer datos rápidamente y un "Addinns" de Rstudio que es brillante por su simplicidad: 'ggplot2 builder'. Fanny Meyer and Victor Perrier (2019). esquisse: Explore and Visualize Your Data Interactively. R package version 0.2.1. https://CRAN.R-project.org/package=esquisse
    ggplot2 builder de la librería esquisse

Continuar con tabulaR

Una vez terminado este documento puede:



Última actualización: 20201116-1214 DOI

Volver a Mod 2: Gráficos con ggplot2