class: center, middle, titular background-size: contain <img style="border-radius: 50%;" src="img/masapp.jpg" width="250px"/> # Capítulo 4: Gramática de gráficos con `ggplot2` ## **CAPACITACIÓN** #### LINDA CABRERA ORELLANA #### Mayo, 2023 --- .pull-left[ # Contenido del Capítulo 4 - Creación de gráficos con `ggplot2` * Gramática de los gráficos * Data * Estética * Geometrías * Facetas * Práctica 4.1 * Más Estética * Transformaciones Estadísticas * Coordenadas y Escalas * Temas visuales ] .pull-right[ # Paquetes a utilizar *
`library(tidyverse)` *
`library(readr)` *
`library(dplyr)` *
`library(ggplot2)` *
`library(magrittr)` *
`library(RColorBrewer)` ] --- class: middle, center, inverse
# Creación de gráficos con `ggplot2` --- background-image: url("img/grammar.png") background-size: contain --- ## Gramática de los gráficos - **Data:** datos sin procesar que desea trazar. - **Geometrías `geom_:`** formas geométricas que representarán los datos. - **Estética `aes()`:** estética de los objetos geométricos y estadísticos, como posición, color, tamaño, forma y transparencia. - **Escalas `scale_`:** asignaciones entre los datos y las dimensiones estéticas, como el rango de datos para trazar el ancho o los valores de los factores para los colores. - **Transformaciones estadísticas `stat_`:** resúmenes estadísticos de los datos, como cuantiles, curvas ajustadas y sumas. - **Sistema de coordenadas `coord_`:** transformación utilizada para mapear coordenadas de datos en el plano del rectángulo de datos. - **Facetas `facet_`:** disposición de los datos en una cuadrícula de gráficos. - **Temas visuales `theme()`:** los valores predeterminados visuales generales de una trama, como el fondo, las cuadrículas, los ejes, el tipo de letra predeterminado, los tamaños y los colores. <br> <br> <br> <br> .footnote[ [Referencias de ggplot2](https://ggplot2.tidyverse.org/reference/) | [ggplot2.tidyverse.org](https://ggplot2.tidyverse.org/) ] --- ## Data .pull-left[ Un **ggplot** necesita especificar mínimo tres cosas: los datos, la estética y una geometría. Siempre comenzamos a definir un objeto de trazado llamando a la **data** mediante `data %>% ggplot()` que simplemente le dice a `ggplot2` que vamos a trabajar con esos datos. Primero, cargamos el paquete `ggplot2` que es parte del `tidyverse`. ```r library(ggplot2) ``` ```r ventas %>% ggplot() ``` ] .pull-right[ <!-- --> ] --- ## Estética **Aesthetics** significa describir un objeto en nuestros gráficos. Sin estética no tenemos nada que mostrar en nuestros gráficos. Las variables del conjunto de datos se asignan a propiedades visuales de gráficos con **aesthetics mapping**. Depende del tipo de gráfico estadístico que estemos produciendo, pero generalmente mapeamos: * una variable que se mostrará en el eje `\(x\)` * una variable que se mostrará en el eje `\(y\)` (en algunos casos solo necesitamos mapear a un solo eje) * se pueden asignar otras variables al color, la forma, el tamaño, el color de relleno, etc. del objeto. --- background-image: url("img/aesthetics.png") background-size: contain --- ## Estética .pull-left[ En la mayoría de los casos, es posible que desee trazar una o dos variables: una en el eje `\(x\)` y otra en el eje `\(y\)`. Estas son estéticas posicionales y, por lo tanto, agregamos `aes(x = var1, y = var2)` a la llamada **ggplot()**. Sin embargo, también hay casos en los que hay que especificar una o incluso tres o más variables. ```r ventas %>% ggplot(aes(x=TOTAL_VENTAS, y=TOTAL_COMPRAS)) ``` ] .pull-right[ <!-- --> ] --- ## Geometrías .pull-left[ Hay muchas geometrías diferentes (llamadas **geoms** porque cada función generalmente comienza con `geom_`) que se pueden agregar a un ggplot de forma predeterminada. Tenemos que decirle a `ggplot2` qué estilo queremos usar, por ejemplo, agregando `geom_point()` para crear un gráfico de puntos o gráfico de dispersión. ```r ventas %>% ggplot(aes(x=TOTAL_VENTAS, y=TOTAL_COMPRAS)) + geom_point() ``` ] .pull-right[ <!-- --> ] --- background-image: url("img/geoms.png") background-size: contain --- ## Facetas Las facetas dividen un conjunto en subconjuntos basados en los valores de uno o más variables categóricas. * **Facet** es un objeto que crea muchos gráficos pequeños que son variaciones de un solo gráfico. * Los datos se dividen en **grupos** (facetas) y los datos se trazan en sus propios gráficos usando el mismo sistema de coordenadas. * Tenemos dos opciones al generar facetas: * Gráfico dividido según filas y columnas: `facet_grid()` * Envolver subconjuntos en columnas: `facet_wrap()` --- background-image: url("img/facet.png") background-size: contain --- .panelset[ .panel[.panel-name[facet_grid1] .pull-left[ ```r ventas %>% ggplot(aes(x=TOTAL_VENTAS, y=TOTAL_COMPRAS)) + geom_point() + facet_grid(.~MES) ``` ] .pull-right[ <!-- --> ] ] .panel[.panel-name[facet_grid2] .pull-left[ ```r ventas %>% ggplot(aes(x=TOTAL_VENTAS, y=TOTAL_COMPRAS)) + geom_point() + facet_grid(MES~.) ``` ] .pull-right[ <!-- --> ] ] .panel[.panel-name[facet_grid3] .pull-left[ ```r ventas %>% filter(PROVINCIA %in% c("PICHINCHA", "GUAYAS", "AZUAY")) %>% ggplot(aes(x=TOTAL_VENTAS, y=TOTAL_COMPRAS)) + geom_point() + facet_grid(PROVINCIA~MES) ``` ] .pull-right[ <!-- --> ] ] .panel[.panel-name[facet_wrap] .pull-left[ ```r ventas %>% ggplot(aes(x=TOTAL_VENTAS, y=TOTAL_COMPRAS)) + geom_point() + facet_wrap(~MES, ncol = 6) ``` ] .pull-right[ <!-- --> ] ] ] --- background-color: var(--azul-claro) class: middle, center, inverse
## PRÁCTICA 4.1 --- #
Práctica 4.1 1. Recrea el código R necesario para generar el siguiente gráfico: <!-- --> --- ## Más Estética .pull-left[ Los gráficos pueden tener más de una **geometría**, en este caso tienen un gráfico de puntos y de forma superpuesta un gráfico de líneas suavizadas. ```r ventas %>% filter(PROVINCIA %in% c("PICHINCHA", "GUAYAS", "AZUAY")) %>% ggplot(aes(x = TOTAL_VENTAS, y = TOTAL_COMPRAS)) + geom_point() + geom_smooth() ``` ] .pull-right[ <!-- --> ] --- ## Más Estética .pull-left[ Podemos visualizar más variables en las geometrías, agregando atributos **aesthetics** en la geometría. ```r ventas %>% filter(PROVINCIA %in% c("PICHINCHA", "GUAYAS", "AZUAY")) %>% ggplot(aes(x = TOTAL_VENTAS, y = TOTAL_COMPRAS)) + geom_point(aes(color = MES, shape = PROVINCIA)) + geom_smooth() ``` ] .pull-right[ <!-- --> ] --- ## Transformaciones estadísticas **Stats** son métodos que alteran la posición de las geometrías. Podemos representar más de una estadística en una figura. La capa de **Stats** representa una forma alternativa de crear una capa, ya que es una transformación del conjunto de datos original. Con las estadísticas, creamos variables adicionales (transformadas) para mapear la estética. Los métodos estadísticos más importantes disponibles para los gráficos se dividen en cinco clases: * **bin** (particiones y mallas - para histogramas) * **summary** (estadísticas básicas: media, mediana, desviación, …) * **region** (límites de intervalo y región) * **smooth** (regresión, smoothing, interpolación y estimación de densidad) * **link** (métodos para calcular bordes de gráficos basados en un conjunto de nodos o puntos) --- ## Transformaciones estadísticas Hay docenas de capas de **Stats** especificadas con un `stat_function`. La mayoría de los geoms y las estadísticas vienen en pares que casi siempre se usan en conjunto. La siguiente tabla contiene los pares entre geometrías y estadísticos que se usan en conjunto. .pull-left[ | geometría | estadístico | |---------------------|---------------------| | `geom_bar()` | `stat_count()` | | `geom_point()` | `stat_identity()`, `stat_sum()` | | `geom_line()` | `stat_identity()` | | `geom_bin2d()` | `stat_bin_2d()` | | `geom_boxplot()` | `stat_boxplot()` | | `geom_contour()` | `stat_contour()` | | `geom_count()` | `stat_sum()` | | `geom_density()` | `stat_density()` | | `geom_density_2d()` | `stat_density_2d()` | ] .pull-right[ | geometría | estadístico | |---------------------|---------------------| | `geom_hex()` | `stat_hex()` | | `geom_freqpoly()` | `stat_bin()` | | `geom_histogram()` | `stat_bin()` | | `geom_qq_line()` | `stat_qq_line()` | | `geom_qq()` | `stat_qq()` | | `geom_quantile()` | `stat_quantile()` | | `geom_smooth()` | `stat_smooth()` | | `geom_violin()` | `stat_violin()` | | `geom_sf()` | `stat_sf()` | ] --- ## Transformaciones estadísticas .pull-left[ Mostraremos las diferencias entre gráficos que muestran datos tal como lucen y gráficos que muestran datos transformados (statistics layer). Analizaremos la información del cantón ESMERALDAS: ```r esmeraldas <- ventas %>% filter(CANTON=="ESMERALDAS") ``` Graficamos un `geom_point()`, `geom_line()` y `geom_smooth()` con nuestros datos `buenosD` ```r esmeraldas %>% ggplot(aes(x=TOTAL_COMPRAS, y=TOTAL_VENTAS)) + geom_point() + geom_line() + geom_smooth() ``` ] .pull-right[ <!-- --> ] --- ## Transformaciones estadísticas: `geom_point()` .pull-left[ Cada `geom_` tiene por default un `stat` (pag.21), argumento que me sirve para convertir un gráfico que muestra datos como son a un gráfico de datos transformados. Graficando sólo un gráfico de puntos: ```r esmeraldas %>% ggplot(aes(x=TOTAL_COMPRAS, y=TOTAL_VENTAS)) + geom_point() ``` ] .pull-right[ <!-- --> ] --- ## Transformaciones estadísticas: `geom_point(stat = "identity")` .pull-left[ Graficando un gráfico de puntos transformado con "identity": ```r esmeraldas %>% ggplot(aes(x=TOTAL_COMPRAS, y=TOTAL_VENTAS)) + geom_point(stat = "identity") ``` **¡NO HAY DIFERENCIA!** ] .pull-right[ <!-- --> ] --- ## Transformaciones estadísticas: `geom_point(stat = "smooth")` .pull-left[ Graficando un gráfico de puntos transformado con "smooth": ```r esmeraldas %>% ggplot(aes(x=TOTAL_COMPRAS, y=TOTAL_VENTAS)) + geom_point(stat = "smooth") ``` Ahora si hay diferencia, los puntos toman la forma de un `geom_smooth()` o líneas suavizadas. ] .pull-right[ <!-- --> ] --- ## Transformaciones estadísticas: `geom_smooth(stat = "identity")` .pull-left[ Graficando un gráfico smooth (lineas suavizadas) transformado con "identity": ```r esmeraldas %>% ggplot(aes(x=TOTAL_COMPRAS, y=TOTAL_VENTAS)) + geom_smooth(stat = "identity") ``` Aunque `geom_smooth()` suaviza las líneas, el argumento `stat = "identity"` forza a que la línea siga los datos como son. ] .pull-right[ <!-- --> ] --- ## Transformaciones estadísticas: `stat_summary()` .pull-left[ Puedes usar `stat_summary()` para resumir los valores de `\(y\)` para cada valor único de `\(x\)`, para así resaltar el resumen que se está computando: ```r ventas %>% filter(REGION == "COSTA") %>% ggplot(aes(x = PROVINCIA, y = TOTAL_VENTAS)) + geom_jitter(alpha=0.5, size=3, color="orchid4") + stat_summary(fun.min = min, fun.max = max, fun=median, size=1, color="rosybrown2") ``` ] .pull-right[ <!-- --> ] --- ## Coordenadas y Escalas Son conjuntos que ubican puntos en el espacio. Generalmente, vemos las coordenadas como esquemas para mapear elementos de conjuntos para objetos geométricos. Las coordenadas más conocidas son las **coordenadas cartesianas**, donde el punto es ubicado en un plano cartesiano por su distancia a dos rectas que se cortan. Hay diferentes **sistemas de coordenadas**. ¿Por qué usar diferentes sistemas? Una razón es simplificar la visualización de gráficos. Las transformaciones de coordenadas pueden cambiar algunos gráficos curvilíneos a lineales. ggplot2 proporciona diferentes sistemas de coordenadas. --- background-image: url("img/coordinate.png") background-size: contain --- ## Coordenadas y Escalas .panelset[ .panel[.panel-name[coord_flip] .pull-left[ ```r ventas %>% filter(REGION == "COSTA") %>% ggplot(aes(x = PROVINCIA, y = TOTAL_VENTAS)) + geom_boxplot() ``` <!-- --> ] .pull-right[ ```r ventas %>% filter(REGION == "COSTA") %>% ggplot(aes(x = PROVINCIA, y = TOTAL_VENTAS)) + geom_boxplot() + coord_flip() ``` <!-- --> ] ] .panel[.panel-name[coord_polar] .pull-left[ ```r ventas %>% filter(REGION == "COSTA") %>% ggplot(aes(x = PROVINCIA)) + geom_bar() ``` <!-- --> ] .pull-right[ ```r ventas %>% filter(REGION == "COSTA") %>% ggplot(aes(x = PROVINCIA)) + geom_bar() + coord_polar() ``` <!-- --> ] ]] --- ## Temas visuales El tema se usa para controlar todos los elementos que no son datos en la trama. **ggplot2** proporciona valores predeterminados para la capa del tema (puede dejarlo como está). Puede anular el tema predeterminado, por ejemplo, con: - **theme_bw()** tema en blanco y negro - **theme()** función para ajustar la configuración de temas individuales - **element_** crea funciones para modificar la configuración del tema .pull-left[ Temas completos: `theme_grey()` `theme_bw()` `theme_light()` `theme_dark()` `theme_classic()` `theme_void()` ] .pull-right[ Elementos de un tema: `margin()` `element_blank()` `element_rect()` `element_line()` `element_text()` ... ] --- background-image: url("img/theme.png") background-size: contain --- background-image: url("img/grafico1.png") background-size: contain --- ## Temas: predeterminados .pull-left[ ```r ventas %>% filter(REGION == "COSTA") %>% ggplot(aes(x=TOTAL_COMPRAS, y=TOTAL_VENTAS)) + geom_point() + theme_classic() ``` ] .pull-right[ <!-- --> ] --- ## Temas: colores .panelset[ .panel[.panel-name[Código] ```r ventas %>% filter(REGION == "COSTA") %>% ggplot(aes(x=TOTAL_COMPRAS, y=TOTAL_VENTAS, color = PROVINCIA)) + geom_point() + theme_classic() ``` ] .panel[.panel-name[Gráfico] <!-- --> ] ] --- ## Temas: colores .panelset[ .panel[.panel-name[Código] ```r library(RColorBrewer) ventas %>% filter(REGION == "COSTA") %>% ggplot(aes(x=TOTAL_COMPRAS, y=TOTAL_VENTAS, color = PROVINCIA)) + geom_point() + scale_color_brewer(palette = "Dark2") ``` ] .panel[.panel-name[Gráfico] <!-- --> ] ] --- ## Temas: etiquetas .panelset[ .panel[.panel-name[Código] ```r ventas %>% filter(REGION == "COSTA") %>% ggplot(aes(x=TOTAL_COMPRAS, y=TOTAL_VENTAS, color = PROVINCIA)) + geom_point() + scale_color_brewer(palette = "Dark2") + labs(x = "Total de Compras (en millones)", y = "Total de Ventas (en millones)", title = "Total de Compras vs Total de Ventas", subtitle = "Recaudaciones según SRI 2022", caption = "Fuente: https://www.sri.gob.ec/datasets", color = "Provincia") ``` ] .panel[.panel-name[Gráfico] <!-- --> ] ] --- ## Temas: escalas y coordenadas .panelset[ .panel[.panel-name[Código] ```r ## cambiar escala de puntos con size y cambiar etiqueta ventas %>% filter(REGION == "COSTA") %>% ggplot(aes(x=TOTAL_COMPRAS/1000000, y=TOTAL_VENTAS/1000000, color = PROVINCIA, size = EXPORTACIONES/1000000)) + geom_point(alpha = 0.5) + scale_color_brewer(palette = "Dark2") + labs(x = "Total de Compras (en millones)", y = "Total de Ventas (en millones)", title = "Total de Compras vs Total de Ventas", subtitle = "Recaudaciones según SRI 2022", caption = "Fuente: https://www.sri.gob.ec/datasets", color = "Provincia", size = "Exportaciones") ``` ] .panel[.panel-name[Gráfico] <img src="4_ggplot2_2ed_files/figure-html/tv12-1.png" width="100%" style="display: block; margin: auto;" /> ] ] --- ## Temas: leyendas .panelset[ .panel[.panel-name[Código] ```r ## modificar leyendas con theme() grafico + theme(legend.position = "bottom", #posición de las leyendas en la parte inferior legend.box = "vertical", #se acomodaron la leyenda de equipos y salarios de forma vertical legend.background = element_blank(), #fondo de las leyendas legend.key = element_rect(fill = "grey92", color = "grey92"), #key es la base de las geometrías de las leyendas text = element_text(colour = "grey45", size = 13), plot.title = element_text(face = "bold", size = 20, colour = "grey30"), #formato del título del gráfico plot.subtitle = element_text(size = 18, colour = "grey40"), #formato del subtítulo del gráfico plot.caption = element_text(size = 10), axis.text = element_text(color = "grey40"), plot.background = element_rect(fill = "grey92"), #fondo de todo el gráfico panel.grid.minor = element_blank()) ``` ] .panel[.panel-name[Gráfico] <img src="img/grafico1.png" width="80%" style="display: block; margin: auto;" /> ] ] --- # Algunos sitios de interés * [Códigos visualizaciones desafío #30díasdegráficos](https://github.com/sporella/nightingale) * [#30DayMapChallenge](https://github.com/sporella/30daymap) * [Gráficos Estadísticos con R](https://cran.r-project.org/doc/contrib/grafi3.pdf) * [Gráficos avanzados con ggplot](https://rua.ua.es/dspace/bitstream/10045/69767/1/Modulo_4_-_Graficos_avanzados_con_ggplot2.pdf) * Tukey, John (1977), Exploratory Data Analysis, Addison-Wesley. * Velleman, Paul and Hoaglin, David (1981), The ABC's of EDA: Applications, Basics, and Computing of Exploratory Data Analysis, Duxbury. * Wilkinson (2005). The Grammar of Graphics. 2nd ed. Statistics and Computing. Springer. * Wickham (2010). A Layered Grammar of Graphics. Journal of Computational and Graphical Statistics --- class: middle, center, inverse <br> <br> # Gramática de gráficos con `ggplot2` ## **CAPÍTULO 4** <br> <br> .center[ ### [@MasappEC
](https://www.facebook.com/MasappEC/) ### [@Masappdata
](https://twitter.com/Masappdata) ] .pull-right[ Para dudas y preguntas:
Linda Cabrera O. (+34 924 609 588) ]