---
################################################################
# #
# Cliquear "Run Document" en RStudio para ejecutar el tutorial #
# #
################################################################
title: "Asignando propiedades estéticas a los datos"
author: "H. Antonio Vazquez Brust remixando a Claus O. Wilke"
output: learnr::tutorial
runtime: shiny_prerendered
---
```{r setup, include=FALSE}
library(learnr)
library(ggplot2)
knitr::opts_chunk$set(echo = FALSE, comment = "")
# Datos de temperatura, cortesía de https://www.kaggle.com/sudalairajkumar/daily-temperature-of-major-cities
temps <- dataviz::temps
temps_beirut <- temps[temps$city == "Beirut",]
```
## Introducción
Aquí practicaremos un concepto central de `ggplot`, la asignación (_mapping_ en inglés) de atributos estéticos a los valores que toma una variable. Dicho de otra forma, como mostrar de modo perceptible a la vista la diferencia entre valores: con distintos colores, distintos tamaños, distintas posiciones en un gráfico, etc.
Usaremos el paquete de R [**ggplot2**](https://ggplot2.tidyverse.org/), que incluye funciones para realizar una gran variedad de visualizaciones.
```{r library-calls, echo = TRUE, eval = FALSE}
# cargar la librería que vamos a usar
library(ggplot2)
```
El data set con el que practicaremos contiene la temperatura promedio para cada día del 2019 en la ciudad de Beirut, Líbano:
```{r temps-beirut}
temps_beirut
```
## Uso básico de `ggplot`
Si le pasamos un dataframe a `ggplot()`, sin agregar nada más, obtenemos un gráfico vacío:
```{r ggplot-vacio, exercise=TRUE}
ggplot(temps_beirut)
```
¡Vendría a ser una especie de lienzo en blanco!
Esto es porque necesitamos definir al menos una geometría (el recurso visual con el que vamos a mostrar la información, como líneas, puntos, barras, etc.) y al menos una asignación estética (especificar cuales variables queremos mostrar, y que atributo estético va a representar sus valores, como el color, el tamaño, la transparencia, etc.).
`ggplot()` implementa un marco teórico para la creación de visualizaciones, ["la gramática de los gráficos"](https://www.slideshare.net/0xdata/leland-wilkinson-h2oai-the-grammar-of-graphics-and-the-future-of-big-data-visualization-h2o-world-2019-nyc). Ésta permite expresar en forma concisa los componentes de un gráfico:
```{r out.width="100%"}
knitr::include_graphics("https://bitsandbricks.github.io/img/ggplot_resumen.png")
```
_diagrama de [David Keyes](https://rfortherestofus.com/)_
¿Cómo funciona ésto en la práctica? El caso de uso más simple de ggplot consiste en:
- una llamada a la función `ggplot()`, pasándole un dataset y una "asignación de atributos estéticos" (_aesthetic mapping_ en inglés) usando `aes()`
- al menos una capa "geom", que define el recurso gráfico que mostrará los datos; por ejemplo `geom_line()` para dibujar líneas o `geom_point()` para dibujar puntos.
A intentarlo. Asignemos la columna `day_of_year` a la posición en el eje de las $x$, la columna `temperature` a las $y$, y usemos `geom_line()` para mostrar los datos.
```{r ggplot, exercise=TRUE}
ggplot(temps_beirut, aes(x = ___, y = ___)) +
___()
```
```{r ggplot-hint}
ggplot(temps_beirut, aes(x = day_of_year, y = temperature)) +
geom____()
```
```{r ggplot-solution}
ggplot(temps_beirut, aes(x = day_of_year, y = temperature)) +
geom_line()
```
Ahora otra vez, pero usando `geom_point()` en vez de `geom_line()`.
```{r ggplot2, exercise=TRUE}
ggplot(temps_beirut, aes(x = day_of_year, y = temperature)) +
___()
```
```{r ggplot2-solution}
ggplot(temps_beirut, aes(x = day_of_year, y = temperature)) +
geom_point()
```
Y ahora intercambiemos las columnas que antes asignamos a las $x$ y a las $y$:
```{r ggplot3, exercise=TRUE}
ggplot(temps_beirut, aes(x = ___, y = ___)) +
geom_point()
```
```{r ggplot3-solution}
ggplot(temps_beirut, aes(x = temperature, y = day_of_year)) +
geom_point()
```
## Otras _geoms_ más complejas
Pueden elegir entre una variada colección de geoms para hacer toda clase de gráficos. Por ejemplo, `geom_boxplot()` crea _boxplots_ (o ["diagramas de caja"](https://economipedia.com/definiciones/diagrama-de-caja.html)). Al hacer boxplots es común mostrar un gráfico separado para cada categoría presente en la data a mostrar, usando para eso el eje de las $x$ o de las $y$. ¡Hagamos eso mismo! Pongamos `month` en el eje $x$ (como variable categórica), `temperature` en el eje de las $y$, y a dibujar cajas con `geom_boxplot()`.
```{r ggplot-boxplot, exercise=TRUE}
ggplot(temps_beirut, aes(x = ___, y = ___)) +
___()
```
```{r ggplot-boxplot-hint}
ggplot(temps_beirut, aes(x = month, y = temperature)) +
___()
```
```{r ggplot-boxplot-solution}
ggplot(temps_beirut, aes(x = month, y = temperature)) +
geom_boxplot()
```
```{r ggplot-boxplot2, exercise=TRUE}
ggplot(___) +
___()
```
```{r ggplot-boxplot2-hint}
ggplot(temps_beirut, aes(x = ___, y = ___)) +
geom_boxplot()
```
```{r ggplot-boxplot2-solution}
ggplot(temps_beirut, aes(x = temperature, y = month)) +
geom_boxplot()
```
Más adelante vamos a regresar a los boxplots, explicando cómo se interpretan.
## Agregando color
Ahora pasamos a trabajar con el dataset `temps`, que es similar a `temps_beirut` pero contiene registros para tres ubicaciones adicionales:
```{r temperatures, echo = TRUE}
temps
```
Hagamos un gráfico de líneas mostrando `temperature` para cada `day_of_year`, usando el atributo estético _color_ para diferencias las líneas según la ciudad que representan.
```{r ggplot-color, exercise=TRUE}
ggplot(temps, aes(x = ___, y = ___, color = ___)) +
___()
```
```{r ggplot-color-hint}
ggplot(temps, aes(x = day_of_year, y = temperature, color = ___)) +
geom_line()
```
```{r ggplot-color-solution}
ggplot(temps, aes(x = day_of_year, y = temperature, color = city)) +
geom_line()
```
Vamos de nuevo, esta vez usando `city` como variable en el eje $y$, y `temperature` a representar con color. Este gráfico queda mejor usando`geom_point()`.
```{r ggplot-color2, exercise=TRUE}
ggplot(___) +
___()
```
```{r ggplot-color2-hint}
ggplot(temps, aes(x = ___, y = ___, color = ___)) +
geom_point()
```
```{r ggplot-color2-solution}
ggplot(temps, aes(x = day_of_year, y = city, color = temperature)) +
geom_point()
```
(Tip: Probar con `geom_point(size = 5)` para mostrar puntos más grandes.)
## Usando el atributo estético `fill`
Algunas geoms permiten usar el atributo estético `fill`, que es similar `color` pero se aplica como relleno, "pintando" por dentro áreas como las barras de un gráfico o las regiones en un mapa (`color`, en cambio, se usa para líneas y puntos). Por ejemplo, podemos usar el atributo estético `fill` con `geom_boxplot()` para pintar el interior de cada caja. Vamos a probarlo. Generemos un gráfico de `month` en las $x$, `temperature` en las $y$, y coloreemos el interior de cada caja según su ciudad.
```{r ggplot-fill, exercise=TRUE}
ggplot(temps, ___) +
___()
```
```{r ggplot-fill-hint}
ggplot(temps, aes(x = month, y = ___, fill = ___)) +
geom_boxplot()
```
```{r ggplot-fill-solution}
ggplot(temps, aes(x = month, y = temperature, fill = city)) +
geom_boxplot()
```
¿Podemos pintar las líneas de las cajas según el mes, y pintar el interior según la ubicación? Veamos.
```{r ggplot-color-fill, exercise=TRUE}
ggplot(temps, ___) +
geom_boxplot()
```
```{r ggplot-color-fill-hint}
ggplot(temps, aes(x = month, y = ___, fill = ___)) +
geom_boxplot()
```
```{r ggplot-color-fill-solution}
ggplot(temps, aes(x = month, y = temperature, color = month, fill = city)) +
geom_boxplot()
```
El gráfico que obtuvimos funciona como recordatorio de que en muchas ocasiones la cantidad de recursos visuales volcados resulta inversamente proporcional a su legibilidad. En general, simple es bueno... pero también conviene saber que podemos combinar varias estéticas dentro de `aes()` cuando resulte necesario.
## Atributos estéticos fijos
Muchos de los atributos estéticos -como `color`, `fill`, y también `size` que cambia el tamaño de puntos y grosor de líneas- pueden ser usados como parámetros fijos para una geom; es decir, que no cambien de acuerdo a los valores de una variable, sino que son iguales para todos las figuras graficadas. Esto se logra definiendo un valor específico, y fuera del llamado a `aes()`. Por ejemplo, `color = "blue"` en lugar de la asignación de una variable, como `aes(color = city)`. Nótese la diferencia: dentro de la función `aes()`, no definimos colores específicos, ggplot se encarga de eso. Sólo decimos que los valores encontrados en la columna `city` deben corresponder a diferentes colores. (Más adelante vamos a aprender como indicarle a ggplot que use escalas de colores específicas cuando asigna colores por variable).
Intentémoslo con el ejemplo del boxplot en la sección anterior. Asignemos el color como atributo dependiente de la ciudad, pero dejemos el color de las líneas fijo en color azul marino (`"navy blue"`) de acuerdo a los [nombres de colores que R sabe interpretar](http://www.stat.columbia.edu/~tzheng/files/Rcolor.pdf)
```{r ggplot-params, exercise=TRUE}
ggplot(temps, ___) +
___(___)
```
```{r ggplot-params-hint}
ggplot(temps, aes(x = month, y = temperature, fill = ___)) +
geom_boxplot(color = ___)
```
```{r ggplot-params-solution}
ggplot(temps, aes(x = month, y = temperature, fill = city)) +
geom_boxplot(color = "navyblue")
```
Ahora al revés. Asignemos la variable `city` al color de las líneas, pero dejemos el relleno de las cajas fijo en color `"navyblue"`.
```{r ggplot-params2, exercise=TRUE}
ggplot(temps, ___) +
___(___)
```
```{r ggplot-params2-hint}
ggplot(temps, aes(x = month, y = temperature, color = ___)) +
geom_boxplot(fill = ___)
```
```{r ggplot-params2-solution}
ggplot(temps, aes(x = month, y = temperature, color = city)) +
geom_boxplot(fill = "navyblue")
```
¡Y con eso terminamos!
Para seguir practicando, pueden obtener así los datos que hemos usado para los ejemplos:
```{r eval=FALSE, echo=TRUE}
temps <- dataviz::temps
temps_beirut <- temps[temps$city == "Beirut",]
```
Y como bibliografía, un excelente recurso es libro *Data Visualization - A practical introduction* por Kieran Healy. Se puede consultar en línea, y tenemos el capítulo dedicado a los fundamentos de `ggplot` aquí: ["Make a plot":](https://socviz.co/makeplot.html)
```{r out.width="60%", fig.align="center"}
knitr::include_graphics("https://socviz.co/assets/dv-cover-pupress.jpg")
```