En la última entrada analizamos los gráficos de correlación, en los que básicamente relacionabamos dos variables que, teóricamente, se encuentran correlacionadas-valga la redundancia-o bien, donde una depende de la otra. En este caso vamos a hacer algo parecido, ya que de igual manera vamos a relacionar algunas variables pero con la diferencia de que ahora las vamos a ordenar para hacer un ranking, ya que de ésto se tratarán los gráficos de ésta entrada.
Cuando queremos hacer un gráfico que nos muestre a aquellas variables (países, personas, riquezas, etc) que han tenido más relevancia en, por ejemplo, un cierto periodo de tiempo, la mejor opción que tenemos para graficar eso son éste tipo de barplots. La lógica es la misma que con un gráfico de divergencia, pero con la diferencia de que en éste tipo de gráficos no solemos tener valores negativos, por lo que suelen estar pegados a la izquierda del eje.
Veamos un ejemplo de ello en R. Vamos a usar la base de datos gapminder_unfiltered
del paquete gapminder
, ya que cuenta con variables de tipo caracter que nos serán útiles para éste ejercicio. Primero que nada cargamos las librerias:
# Cargamos las librerías
library(echarts4r)
library(scales)
library(ggbump)
library(ggplot2)
library(dplyr)
library(gapminder)
library(CGPfunctions)
Antes de continuar, quiero mencionar que existen varias formas de reordenar la base de datos como la necesitamos, pero la que a mi parecer es la más práctica es concatenando las funciones usadas a continuación con el operador %>%
. Te recomiendo usarlo cuando trabajes con tidyverse
, ya que te ahorrará algo de tiempo de escritura.
# Filtramos y reordenamos la base de datos
base_1 <- filter(gapminder_unfiltered, year == 1957) %>% # Para filtrar a un año
arrange(pop) %>% # Para reordenar los valores de mayor a menor
top_n(10, pop) # Para seleccionar los primeros 10 valores
base_1 %>%
e_charts(x = country) %>%
e_bar(pop, legend = FALSE, name = "Población") %>%
e_labels(position = "right") %>%
e_tooltip() %>%
e_title("Población por país", "10 países con mayor población") %>%
e_flip_coords() %>%
e_y_axis(splitLine = list(show = FALSE)) %>%
e_color(color = "#5dabc9", background = NULL) %>%
e_theme("london") %>%
e_x_axis(show = FALSE)
Hagamos un paréntesis para analizar un poco el código anterior, ya que no me gusta escribir cosas sin que entiendas por qué están ahí. Si leíste la entrada sobre bases de datos disponible aquí entonces se harán familiares las primeras dos funciones usadas. Primero, utilizamos filter()
para poder filtrar la base únicamente a un año, en este caso a 1957, después utilizamos arrange()
para reordenar los valores de mayor a menor y, finalmente, usamos top_n()
para obtener los primeros 10 valores de la base de datos que previamente filtramos, todo esto concatenado en la misma función con el operador %>%
. Pasando al código de la gráfica, primero que nada definimos la base de datos con la que vamos a trabajar (en este caso a la que filtramos previamente), con la función e_charts()
definimos al eje de las \(X\). Con la función e_bar()
definimos los datos que se usarán para un gráfico de barras, además de agregarles una etiqueta. El comando e_flip_coords()
nos invertirá los ejes para tener barras a la izquierda. De hecho el gráfico ya funciona hasta este punto, el resto de comandos son solamente extras, como un cierto color con e_color()
, un tema de fondo con e_theme()
(puedes ver el resto de los temas disponibles escribiendo en la consola ?e_theme()
) y opciones de visualización de datos con e_tooltip()
.
En los siguientes gráficos no voy a detenerme demasiado con el código, me limitaré a poner breves explicaciones ya que la mayoría seguirán una lógica parecida, pero en tanto entiendas como funciona el primer gráfico es más que suficiente para comprender el resto.
Por cierto, seguramente te estarás preguntando por qué la etiqueta del color en e_color()
es un nombre tan raro. Ciertamente no me se de memoria el código de los colores, pero eso no importa, ya que basta con que escribas hex color en el buscador de Google para que nos arroje una pequeña app que nos muestra toda la gama de colores que existe. Debajo de la app nos dirá también el código del color, basta con que escojamos alguno que sea de nuestro agrado y copiemos el código para pegarlo aquí en el gráfico.
Éste gráfico es muy parecido al anterior, ya que se basa igualmente en barras ordenadas, siendo la única diferencia que ahora están ordenadas en el eje de las \(X\) (en éste caso por población). Básicamente, lo único que tenemos que hacer es reordenar los ejes para éste caso. Vamos a ver un ejemplo en R utilizando la misma base filtrada del caso anterior:
# Gráfico de columnas
base_1 %>%
e_charts(x = country) %>%
e_bar(pop, legend = FALSE, name = "Población") %>%
e_labels(position = "top") %>%
e_tooltip() %>%
e_title("Población por país", "10 países con mayor población") %>%
e_y_axis(splitLine = list(show = FALSE)) %>%
e_color(color = "#3269a8", background = NULL) %>%
e_theme("london") %>%
e_x_axis(show = TRUE)
Notese que omití el comando e_flip_coords()
para evitar que el gráfico invierta los ejes. En este caso solo hice pequeñas modificaciones, como escribir TRUE
en la función e_x_axis()
, para que nos muestre los países por con nombre y cambié la paleta de colores para diferenciarlo del otro gráfico.
En este punto te deberías estar preguntando: ¿cuando utilizo la primera y cuando la segunda? Realmente puedes usar cualquiera de las dos para los mismos casos, aunque te recomendaría utilizar la segunda gráfica cuando tengas una mayor cantidad de datos. Procura utilzar la primera cuando tengas no más de 15 barras.
Imaginemos que queremos mostrar una representación más exacta de la magnitud que tenemos en los datos, para ello podemos hacer un gráfico de burbujas ordenadas por tamaño, ya que nos mostrará una mejor proporción de la diferencia existente entre los datos. Vamos a ver un ejemplo en R con un gráfico de puntos ordenados por tamaño que además está animado. Existe la opción de hacer esto con ggplot()
pero me voy a limitar a la forma más sencilla de hacerlo, para evitar complicarte demasido.
# Agregamos una variable z al data frame
base_2 <- mutate(base_1, pop2 = pop)
# Graficamos
base_2 %>%
head(10) %>%
e_charts(country) %>%
e_y_axis(splitLine = list(show = FALSE)) %>%
e_tooltip() %>%
e_title("Población por país", "10 países con mayor población") %>%
e_y_axis(splitLine = list(show = FALSE)) %>%
e_effect_scatter(pop, pop2, symbol_size = 5, name = "Población") %>% # Para darle una animación a las burbujas
e_visual_map(pop2) %>%
e_theme("london") %>%
e_legend(FALSE)
En este caso las burbujas ya están ordenadas por altura (entre más alta se encuentre el valor es mayor), pero además de eso también le añadimos un tamaño a las burbujas para denotar la diferencia existente entre los valores de una manera más clara. Ahora, para poder añadir tamaño a las burbujas este gráfico no puede hacerlo si consideramos a la misma variable \(Y\) como una variable \(Z\) de tamaño, por lo que previamente hicimos uso de la función mutate()
para añadir otra columna que es, simplemente, la misma variable \(Y\) pero considerada como \(Z\), para evitar que el gráfico se genere con errores.
Éstos gráficos suelen ser útiles cuando queremos ver el cambio en las magnitudes de varias variables a lo largo del tiempo, es decir, cómo ha cambiado una variable de un periodo a otro. Aunque no siempre sean gráficos de ranking ordenados si son sumamemnte útiles para ver la progresión de diversas series durante, por ejemplo, 3 periodos de tiempo diferentes. Es recomendable usarlos cuando queremos comparar valores en no más de 5 periodos, pero que éstos periodos tengan una amplitud de tiempo considerable, por ejemplo: 5 años, 10 años, 15 años, etc.
Para este tipo de gráficos vamos a utilizar un paquete llamado CGPfunctions
que nos ahorrará mucho trabajo, ya que facilita mucho la creación de éste tipo de gráficos. Para fines prácticos utilizaremos el ejemplo que viene por default en el paquete. Veamos un gráfico de éste estilo sobre sobrevivientes de cancer durante un periodo de 20 años. Primero que nada veamos los datos, para saber qué estamos graficando:
head(newcancer)
## Year Type Survival
## 1 5 Year Prostate 99
## 2 10 Year Prostate 95
## 3 15 Year Prostate 87
## 4 20 Year Prostate 81
## 5 5 Year Thyroid 96
## 6 10 Year Thyroid 96
Podemos observar que tenemos 3 columnas: Una con el periodo en años, otra con el tipo de cancer y otra con el porcentaje de superviviencia. Notese que cada 4 valores se habla de un mismo tipo de cancer, ya que la base nos estaría indicando que porcentaje de personas sobreviven después de tantos años a cada tipo de cancer. Ahora, vamos a graficar la serie de la siguiente manera, con la función newggslopegraph
:
newggslopegraph(dataframe = newcancer,
Times = Year,
Measurement = Survival,
Grouping = Type,
Title = "Porcentaje de sobrevientes de cancer",
SubTitle = "Datos a 20 años",
Caption = "Espero que te sirva este ejemplo"
)
Lo que podemos notar es que ésta función nos pide por default los siguientes datos: dataframe
para saber qué datos va a utilizar, Times
para saber los periodos temporales a utilizar, Measurement
para saber el valor que va a graficar a lo largo de los periodos temporales y, finalmente, Grouping
para saber como va a agrupar los datos. Vamos a hacer una pequeña base de datos por si no has entendido del todo como funciona la función anterior. Supongamos por ejemplo que queremos saber la aprobación que tiene una ideología política en dos periodos de tiempo para 3 estados diferentes: EDOMEX, Nuevo Leon y Chihuahua, por lo que para ello vamos a proponer 2 fechas diferentes, asignarlas por estado y dar una aprobación fictiia. Vamos a crear el data frame de la siguiente manera:
# Creamos las variables
periodo <-c("01-01-2000","01-01-2010", "01-01-2020", "01-01-2000","01-01-2010", "01-01-2020", "01-01-2000","01-01-2010", "01-01-2020")
estados <- c("EDOMEX", "EDOMEX", "EDOMEX", "Nuevo Leon", "Nuevo Leon", "Nuevo Leon", "Chihuahua", "Chihuahua", "Chihuahua")
aceptacion <- c(50,70,40,30,60,80,40,30,70)
# Creamos el data frame
aprobacion <- data.frame(periodo, estados, aceptacion)
# Visualizamos los datos que hemos creado
head(aprobacion)
## periodo estados aceptacion
## 1 01-01-2000 EDOMEX 50
## 2 01-01-2010 EDOMEX 70
## 3 01-01-2020 EDOMEX 40
## 4 01-01-2000 Nuevo Leon 30
## 5 01-01-2010 Nuevo Leon 60
## 6 01-01-2020 Nuevo Leon 80
Ahora que ya tenemos nuestros datos ficticios podemos pasar a graficar de la misma manera que con los datos de cancer, por lo que tendremos lo siguiente:
# Creamos el gráfico con datos ficticios
newggslopegraph(dataframe = aprobacion,
Times = periodo,
Measurement = aceptacion,
Grouping = estados,
Title = "Porcentaje de aceptación por estados",
SubTitle = "Datos a 10 años",
Caption = "Espero que te sirva este ejemplo"
)
Como vemos, este gráfico nos da una buena visualización de variaciones al estilo ranking, pero es importante que no usemos demasiados periodos de tiempo, ya que tendríamos un grñafico demasiado complicado de interpretar.
Un gráfico de paleta es básicamente lo mismo que un gráfico de barras como el que hicimos al principio, solo que en este caso éstos gráficos suelen darle una mayor atención a lo que es el valor final, más que los gráficos de barras. Suelen ser útiles cuando queremos dejar en claro el valor que estamos graficando al final, además de que éstos gráficos tienen margen para agregar una mayor cantidad de valores.
Veamos un ejemplo en R utilizando los datos que ya teníamos previamente de población. Para éste tipo de gráficos usaremos la función geom_center()
para crear las lineas y la función geom_point()
para crear el punto final en cada linea, tal que:
# Quitamos la notación científica
options(scipen = 999)
# Creamos el gráfico
ggplot(base_1, aes(x=country, y=pop)) +
geom_segment( aes(x=country, xend=country, y=0, yend=pop), color="skyblue") +
geom_point( color="blue", size=4, alpha=0.6) +
theme_bw() +
coord_flip() +
theme(
panel.grid.major.y = element_blank(),
panel.border = element_blank(),
axis.ticks.y = element_blank()
)
Ahora, como podemos observar no tenemos un gráfico ordenado al estilo ranking, por lo que utilizando la función reorder()
e incluyendo dentro a la variable \(X\), la cual estará ordenada en función de la variable \(Y\) ahora si podemos hacer un gráfico de ranking ordenado de mayor a menor, tal que:
# Reordenamos los datos
ggplot(base_1, aes(x=reorder(country, pop), y=pop)) +
geom_segment( aes(x=reorder(country, pop), xend=reorder(country, pop), y=0, yend=pop), color="skyblue") +
geom_point( color="blue", size=4, alpha=0.6) +
theme_bw() +
coord_flip() +
theme(
panel.grid.major.y = element_blank(),
panel.border = element_blank(),
axis.ticks.y = element_blank()
)
Y ahora, para hacerlo más atractivo visualmente, agreguemos títulos, ejes, notas y ajustes de tamaño:
# Dandole formato al gráfico
ggplot(base_1, aes(x=reorder(country, pop), y=pop)) +
geom_segment( aes(x=reorder(country, pop), xend=reorder(country, pop), y=0, yend=pop), color="skyblue") +
geom_point( color="blue", size=4, alpha=0.6) +
theme_bw() +
coord_flip() +
theme(
panel.grid.major.y = element_blank(),
panel.border = element_blank(),
axis.ticks.y = element_blank()
) +
theme(legend.position = "bottom") +
theme(legend.title = element_blank()) +
guides(col = guide_legend(nrow = 1, byrow = TRUE)) +
xlab("País") +
ylab("Población")+
theme(plot.title = element_text(size = 11, face = "bold", hjust = 0)) +
theme(plot.subtitle = element_text(size = 10, hjust = 0)) +
theme(plot.caption = element_text(size = 10, hjust = 0)) +
theme(plot.margin = unit(c(1,1,1,1), "cm")) +
labs(
title = "Ejemplo de un gráfico de paleta de ranking.",
subtitle = "Aquí va un subtítulo",
caption = "Fuente: Elaboración propia. \nNotas: Espero que te sirva este ejemplo."
)
Finalmente, vemos que los números de la parte de abajo son algo difíciles de leer, por lo que usando el paquete scales
vamos agregarle algunas comas a los números con la función scale_y_continuous()
de la siguiente manera:
# Cambiando el formato de los números
ggplot(base_1, aes(x=reorder(country, pop), y=pop)) +
geom_segment( aes(x=reorder(country, pop), xend=reorder(country, pop), y=0, yend=pop), color="skyblue") +
geom_point( color="blue", size=4, alpha=0.6) +
theme_bw() +
coord_flip() +
theme(
panel.grid.major.y = element_blank(),
panel.border = element_blank(),
axis.ticks.y = element_blank()
) +
theme(legend.position = "bottom") +
theme(legend.title = element_blank()) +
guides(col = guide_legend(nrow = 1, byrow = TRUE)) +
xlab("País") +
ylab("Población")+
theme(plot.title = element_text(size = 11, face = "bold", hjust = 0)) +
theme(plot.subtitle = element_text(size = 10, hjust = 0)) +
theme(plot.caption = element_text(size = 10, hjust = 0)) +
theme(plot.margin = unit(c(1,1,1,1), "cm")) +
labs(
title = "Ejemplo de un gráfico de paleta de ranking.",
subtitle = "Aquí va un subtítulo",
caption = "Fuente: Elaboración propia. \nNotas: Espero que te sirva este ejemplo."
)+
scale_y_continuous(labels = comma)
Ahora si, el gráfico ya es mucho más dijerible y presentable. En este caso preferí no convertir el gráfico a objeto y ahorrar lineas de código, ya que me interesa que veas el código final completo para que entiendas perfectamente como funciona el gráfico.
Estos son bastante parecidos a los gráficos de pendiente que vimos hace un par de puntos, pero considerablemente mejores para graficar datos con más periodos de tiempo. Estuve investigando por un rato y encontré un paquete sumamente interesante para crear este tipo de gráficos, llamado ggbump
, el cual es una extensión de Ggplot2. En este caso usaré la documentación que hay al respecto como guía para crear el gráfico, ya que no tengo demasiada experiencia trabajando con éste tipo de gráficos.
¿Recuerdas el gráfico que hice hace un rato sobre aceptación política? Bueno, al ser un gráfico que tiene casi la misma lógica en este caso vamos a utilizar los mismos datos, tal que:
head(aprobacion)
## periodo estados aceptacion
## 1 01-01-2000 EDOMEX 50
## 2 01-01-2010 EDOMEX 70
## 3 01-01-2020 EDOMEX 40
## 4 01-01-2000 Nuevo Leon 30
## 5 01-01-2010 Nuevo Leon 60
## 6 01-01-2020 Nuevo Leon 80
Ahora, la documentación del gráfico nos dice que debemos incluir una variable ranking para enumerar de mayor a menor los datos, por lo que se hará con la ya conocida función mutate()
, sin embargo, en este caso éste tipo de gráficos no aceptan variables de tipo fecha, por lo que vamos a crear una variable nueva que solo incluya el año y hacer otro data frame para este caso, tal que:
# Creamos los periodos considerando solo un año y un data frame nuevo con la función tibble
periodo_año <- c(2000, 2010, 2020, 2000, 2010, 2020, 2000, 2010, 2020)
aprobacion_1 <- tibble(periodo_año, estados, aceptacion)
# Creando una variable extra de ranking
aprobacion_1 <- mutate(aprobacion_1, rank = rank(aceptacion, ties.method = "random")) %>%
group_by(periodo_año) %>%
ungroup()
# Visualizamos los datos
head(aprobacion_1)
## # A tibble: 6 x 4
## periodo_año estados aceptacion rank
## <dbl> <chr> <dbl> <int>
## 1 2000 EDOMEX 50 5
## 2 2010 EDOMEX 70 7
## 3 2020 EDOMEX 40 3
## 4 2000 Nuevo Leon 30 2
## 5 2010 Nuevo Leon 60 6
## 6 2020 Nuevo Leon 80 9
Bien, ahora que ya tenemos la base entonces podemos comenzar a trabajar en el gráfico, tal que:
# Gráfico en su forma más simple
ggplot(aprobacion_1, aes(periodo_año, aceptacion, color = estados)) +
geom_bump()
Bien, ya tenemos un gráfico muy sencillo, pero ahora vamos a darle algo de color, cambiar fondos, paletas de colores, agregar algunos puntos, etc, tal que:
# Cargamos algunos paquetes extra que nos servirán para darle formato al gráfico
pacman::p_load(tidyverse, cowplot, wesanderson)
# Dándole formato al gráfico
ggplot(aprobacion_1, aes(x = periodo_año, y = aceptacion, color = estados)) +
geom_point(size = 4) +
# La función geom_text nos da el nombre de los estados dentro de la gráfica
geom_text(data = aprobacion_1 %>% filter(periodo_año == min(periodo_año)),
aes(x = periodo_año - .1, label = estados), size = 2, hjust = 1) +
geom_text(data = aprobacion_1 %>% filter(periodo_año == max(periodo_año)),
aes(x = periodo_año + .1, label = estados), size = 2, hjust = 0) +
geom_bump(size = 2, smooth = 8) +
# Fondo utilizado con theme_minimal
theme_minimal_grid(font_size = 10, line_size = 0) +
theme(legend.position = "none",
panel.grid.major = element_blank()) +
scale_y_reverse() +
# Escala de colores usada en el manual
scale_color_manual(values = wes_palette(n = 3, name = "GrandBudapest1"))+
guides(col = guide_legend(nrow = 1, byrow = TRUE)) +
### a partir de aquí son los mismos comandos que siempre uso para márgenes y títulos
xlab("Periodo") +
ylab("Ranking")+
theme(plot.title = element_text(size = 11, face = "bold", hjust = 0)) +
theme(plot.subtitle = element_text(size = 10, hjust = 0)) +
theme(plot.caption = element_text(size = 10, hjust = 0)) +
theme(plot.margin = unit(c(1,1,1,1), "cm")) +
labs(
title = "Gráfico de ranking con especializado",
subtitle = "Ejemplo",
caption = "Fuente: Elaboración propia. \nNotas: Espero que te sirva este ejercicio."
)
Ahora ya tenemos un gráfico más bonito y mucho más digerible, con una paleta de colores que, a mi parecer, es bastante más atractiva que la que suele usar ggplot2
po default.
Algo interesante de éste tipo de gráficos es que puedes combinarlos con mapas, pero eso lo veremos en una futura entrada dedicada exclusivamente a la creación de mapas para análsis gráfico.
¡Muchas gracias por leerme! Sería de gran ayuda que compartieras ésta entrada con quien creas que pueda serle útil. Me ayudaría mucho que ésto llegue a más gente.
Esta entrada está dedicada a Alessandra Gutierrez Sosa, quien me apoyó y me inspiró para varios tópicos que vienen aquí
[1] Urias, H. Q., & Salvador, B. R. P. (2014). Estadística para ingeniería y ciencias. Grupo Editorial Patria.
[2] Wickham, H., Chang, W., & Wickham, M. H. (2016). Package ‘ggplot2’. Create Elegant Data Visualisations Using the Grammar of Graphics. Version, 2(1), 1-189.
[3] Kuan, J. (2015). Learning Highcharts 4. Packt Publishing Ltd.
[4] Bivand, R. S., Pebesma, E. J., Gomez-Rubio, V., & Pebesma, E. J. (2013). Applied spatial data analysis with R (Vol. 2). New York: Springer.
[5] Smith, A. (2018). Visual Vocabulary. 4 de marzo de 2020, de Financial Times. Sitio web: https://github.com/ft-interactive/chart-doctor/tree/master/visual-vocabulary
[6] Coene, J. (2017). Maps. 26 de febrero de 2021, de echarts4r Sitio web: https://echarts4r.john-coene.com/articles/map.html
[7] Joberg, D. (2020). ggbump, documentation. 27 de marzo de 2021, de Github Sitio web: https://github.com/davidsjoberg/ggbump