Ésta entrada está dividida en 9 partes, ya que repasaremos al menos 78 diferentes tipos de gráficos.

Cuando trabajamos con estadísticas, macroeconomía, indicadores y bases de datos generalmente una buena forma de transmitir los resultados obtenidos es mediante la creación de gráficos, pero ¿cuál de ellos nos permitirá transmitir la información de manera más clara para el público general? Ciertamente eso depende del tipo de datos que tengamos, la cantidad de ellos, los valores que presentemos e incluso el tema que esté de por medio.

En ésta entrada iremos viendo las diferentes categorías de gráficos para el análisis estadístico, además de ver cada gráfico de su respectiva categoría y el mejor uso que se le puede dar a éste, para que el lector tenga una mejor idea sobre cual será el mejor gráfico para los datos que tenga.

Para ésta entrada haremos uso de los siguientes paquetes de gráficos principalmente: ggplot2, echarts4r, plotly, highcharter, echarts4r.maps, quantmod y HH, además de otras para uso general. Hay que tener en cuenta que estamos utilizando diferentes paquetes con diferentes características cada uno, por lo que en algunos casos hay posibilidad de tener gráficos interactivos, mientras que en otros no.

Las categorías de los gráficos.

Dentro del mundo de la visualización de datos podemos encontrar un sin fin de gráficos individuales, los cuales pertenecen (en su mayoría) a las siguientes categorías principales: Desviación, correlación, ranking, distribución, series de tiempo, magnitudes, porcentajes, análisis espacial y flujos, ¿Cuando es conveniente usar cada uno de ellos? Vamos a analizar qué nos ofrece (y dice) cada categoría de manera individual para averiguarlo a continuación, pero primero carguemos los paquetes necesarios para ésta entrada.

library(ggplot2)
library(echarts4r)
library(echarts4r.maps)
library(plotly)
library(highcharter)
library(quantmod)
library(gapminder)
library(tidyverse)
library(readxl)

Gráficos de desviación

En éste tipo de gráficos lo que nos interesa ver es variaciones en nuestros datos, es decir, variaciones porcentuales principalmente. Generalmente utilizamos indicadores macroeconómicos en éste tipo de gráficos, como por ejemplo el PIB per cápita, la balanza comercial, etc. Veamos a continuación los gráficos usados en éste caso:

Barras de divergencia.

El caso más sencillo de un gráfico de desviación, suele ser una buena opción debido a su simplicidad y facilidad de interpretación. Veamos un ejemplo de ello utilizando la base de datos precargada de gapminder:

# Leemos la base de datos
attach(gapminder)

# Filtramos y reordenamos
base_gdp <- filter(gapminder, year == 1952)
base_gdp <- arrange(base_gdp, desc(gdpPercap))
base_gdp <- base_gdp[2:20,]
base_gdp <- mutate(base_gdp, 
                   "Valor nuevo" = gdpPercap - 10000)

# Graficamos
ggplot(data = base_gdp,
       aes(x = reorder(country, `Valor nuevo`), y = `Valor nuevo`))+ # Definimos ejes X e y
  geom_bar(stat = "identity")+ # Gráfico de barras
  coord_flip()+ # Cambiamos coordenadas
# Bastan éstos comandos para crear el gráfico. El resto son extras de éstetica no necesarios #
  theme_bw()+ # Cambiamos el fondo
  theme(legend.position = "none") + # Posición del título
  theme(legend.title = element_blank()) + 
  guides(col = guide_legend(nrow = 1, byrow = TRUE)) +  
  xlab("País") + 
  ylab("Valor")+ 
  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")) + # Márgenes
  labs(
    title = "Ejemplo de un gráfico de barras de divergencia.",
    subtitle = "Con datos de muestra.",
    caption = "Fuente: Elaboración propia. \nNotas: Este ejemplo puede serte útil."
  ) # Títulos, subtitulos y notas al pie

Podemos agregar color a valores positivos y negativos de la siguiente manera con la órden fill = x > 0 :

ggplot(data = base_gdp,
       aes(x = reorder(country, `Valor nuevo`), y = `Valor nuevo`,
           fill = `Valor nuevo` > 0))+ # Definimos ejes X e y
  geom_bar(stat = "identity")+ # Gráfico de barras
  coord_flip()+ # Cambiamos coordenadas
# Bastan éstos comandos para crear el gráfico. El resto son extras de éstetica no necesarios #
  theme_bw()+ # Cambiamos el fondo
  theme(legend.position = "none") + # Posición del título
  theme(legend.title = element_blank()) + 
  guides(col = guide_legend(nrow = 1, byrow = TRUE)) +  
  xlab("País") + 
  ylab("Valor")+ 
  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")) + # Márgenes
  labs(
    title = "Ejemplo 2 de un gráfico de barras de divergencia.",
    subtitle = "Con datos de muestra.",
    caption = "Fuente: Elaboración propia. \nNotas: Este ejemplo puede serte útil."
  ) # Títulos, subtitulos y notas al pie

Éstos datos en realidad no tienen mucho sentido, ya que son meramente un ejemplo para visualización, pero lo que si tiene sentido es que éste tipo de gráficos son esencialmente útiles cuando queremos graficar variaciones, como podrían ser variaciones en el gasto de una empresa de un año a otro, variaciones porcentuales, etc, ya que nos estaría mostrando aquellos valores que fueron negativos, así como aquellos positivos y cuales tienen un mayor peso.

Gráfico de barras apiladas divergentes.

Éste tipo de gráficos usualmente son útiles cuando tenemos varias columnas que queremos apilar para representar porcentajes de algún tema. Este tipo de gráficos son utilizados principalmente en encuestas que denotan sentimientos en las personas, por ejemplo: Bueno, malo, neutral, etc.

El ejemplo más común en éste tipo de gráficos es una encuesta de satisfacción por parte de los usuarios, así que vamos a crear una encuesta artificial con niveles de satisfacción. Supongamos que queremos saber la opinión de las personas respecto a un grupo de restaurantes de una zona, por lo que hacemos una encuesta que incluya el restaurante al que se refieren los encuestados, y sus niveles de satisfacción divididos por columnas, las cuales nos dirán el número de personas que están “satisfechas” o “insatisfechas” con el servicio de cada restaurante. Para éste ejercicio vamos a utilizar el paquete HH, pero para que funcione correctamente es necesario descargar también el paquete Rmpfr. Éste último generalmente nos va a preguntar si queremos compilar una versión binaria del mismo, es recomendable escribir No en la consola para no tener problemas con la instalación.

Vamos con el ejercicio. Primero, vamos a crear una base de datos con la información ficticia:

# Creamos las variables

Restaurante <- c("Restaurante 1", "Restaurante 2", "Restaurante 3", "Restaurante 4", "Restaurante 5", "Restaurante 6")

"Mal servicio" <- c(1,2,3,2,4,1)
"Servicio regular" <- c(2,2,3,1,5,3)
"Neutro" <- c(15,12,14,11,12,13)
"Buen servicio" <- c(24,25,27,28,23,28)
"Excelente servicio" <-c(8,9,3,8,6,5)

# Creamos el Data Frame

Base_ejemplo <- data.frame(Restaurante, `Mal servicio`, `Servicio regular`, Neutro, `Buen servicio`, `Excelente servicio`)

# Visualizamos los datos

head(Base_ejemplo)
##     Restaurante Mal.servicio Servicio.regular Neutro Buen.servicio
## 1 Restaurante 1            1                2     15            24
## 2 Restaurante 2            2                2     12            25
## 3 Restaurante 3            3                3     14            27
## 4 Restaurante 4            2                1     11            28
## 5 Restaurante 5            4                5     12            23
## 6 Restaurante 6            1                3     13            28
##   Excelente.servicio
## 1                  8
## 2                  9
## 3                  3
## 4                  8
## 5                  6
## 6                  5

Es importante destacar el hecho de que todos los renglones suman 50 en las observaciones, porque estamos suponiendo que le preguntamos a 50 personas sobre su visita a 4 restaurantes distintos. Ahora, vamos a crear el gráfico:

# Cargamos el paquete
library(HH)

# Creamos el gráfico
likert(Restaurante ~., Base_ejemplo, ylab="Restaurante",
       ReferenceZero=3, as.percent=TRUE,
       positive.order=TRUE, 
       main = list("Encuesta de satisfacción por restaurante",x=unit(.55, "npc")), 
       sub= list("Nivel de satisfacción",x=unit(.57, "npc")), 
       strip=FALSE, 
       par.strip.text=list(cex=.7))

Como podemos observar, el gráfico nos divide la información por restaurantes, diciéndonos como se distribuye la satisfacción de los usuarios en cada caso. El comando ~. del principio nos reconoce todas las variables numéricas para agruparlas como las queremos. El comando as.percent nos dice si queremos que el eje de las X esté denotado en porcentajes, por lo que ésto ya es a gusto personal de cada quien. Por otra parte, el comando positive.order nos pregunta si queremos reordenar a los restaurantes por aquellos que tengan niveles de satisfacción más altos, por lo que de no haberlo usado habríamos gráficado simplemente a los restaurantes 1 a 5 en el mismo orden de la base de datos, tal que:

likert(Restaurante ~., Base_ejemplo, ylab="Restaurante",
       ReferenceZero=3, as.percent=TRUE,
       positive.order=FALSE, 
       main = list("Encuesta de satisfacción por restaurante",x=unit(.55, "npc")), 
       sub= list("Nivel de satisfacción",x=unit(.57, "npc")), 
       strip=FALSE, 
       par.strip.text=list(cex=.7))

Ahora, vamos a suponer que los restaurantes del 1 al 3 pertenecen a la Ciudad de México, mientras que los restaurantes del 4 al 6 pertenecen a la Ciudad de Nuevo Leon, por lo que queremos separarlos en dos gráficos diferentes. Ésto lo podemos hacer de la siguiente manera:

# Creamos un vector nuevo con las ciudades
Ciudad <- c("CDMX","CDMX","CDMX", "Nuevo Leon","Nuevo Leon","Nuevo Leon")

# Lo agregamos a la base original
Base_ejemplo1 <- cbind(Base_ejemplo, Ciudad)

# Creamos el gráfico dividido por ciudades

likert(Restaurante ~. | Ciudad ,  Base_ejemplo1, 
       layout=c(1,2),
       scales=list(y=list(relation="free")),
       between=list(y=1),
       strip.left=strip.custom(bg=NULL),
       strip=FALSE,
       par.strip.text=list(cex=1.1, lines=2),
       ylab=NULL, 
       cex=1.2,
       ReferenceZero=3,
       as.percent=TRUE, 
       positive.order=TRUE, 
       main = list("Encuesta de satisfacción por restaurante",x=unit(.55, "npc")), 
       sub= list("Nivel de satisfacción",x=unit(.57, "npc")), 
       resize.height.tuning=1
       )

Como podemos observar, ahora tenemos dos gráficos para denotar la opinión en cada ciudad, lo cual puede ser útil para trabajar con datos más homogeneos.

Gráficos de columna vertebral (spine)

Éste tipo de gráficos de mosaico son bastante útiles cuando queremos ver divergencias entre dos grupos, por ejemplo: Un grupo de hombres y otro de mujeres. Suelen ser utilizados en estúdios médicos principalmente para analizar las reacciones en cada grupo. Es recomendable utilizar éste tipo de gráficos cuando queremos comparar a dos grupos para un estudio en el que se apliquen tratamientos o técnicas similares para cada uno, pero que además tenga subgrupos, ya que nos dirá la proporción de cada uno de ellos que tuvo ciertas reacciones, por lo que podremos ver claramente las diferencias de manera homogénea.

Un buen ejemplo obtenido de la página de Statistics & Actuarial Science que podemos trabajar ahora mismo es un gráfico de espina con los datos Arthritis del paquete vcd. Vamos a ello. Primero veamos la base de datos utilizada:

# Cargamos el paquete con los datos
library(vcd)

# Leemos y vemos la base de datos
attach(Arthritis)
head(Arthritis)
##   ID Treatment  Sex Age Improved
## 1 57   Treated Male  27     Some
## 2 46   Treated Male  29     None
## 3 77   Treated Male  30     None
## 4 17   Treated Male  32   Marked
## 5 36   Treated Male  46   Marked
## 6 23   Treated Male  58   Marked

En el ejemplo de Statistics & Actuarial Science primero invierten los factores de la columna Improved, para tener valores como None en la parte más baja de la gráfica, tras eso crean un dos bases de datos, las cuales se encuentran filtradas por aquellos pacientes a los que se les dió un placebo y aquellos a los que se les dió el tratamiento real, con el objetivo de crear dos gráficas agrupadas para cada caso. El código es el siguiente:

library(vcd)
library(tidyverse)
attach(Arthritis)


Arth <-  mutate(Arthritis, Improved = fct_rev(Improved)) # Para invertir los datos
ArthP <- filter(Arth, Treatment == "Placebo") # Filtro para gráfico de placebo
ArthT <- filter(Arth, Treatment == "Treated") # Filtro para gráfico de tratamiento
opar <- par(mfrow = c(1, 2)) # Para graficar lado a lado ambos casos
spineplot(Improved ~ Sex, data = ArthP, main = "Placebo") # Gráfico placebo
spineplot(Improved ~ Sex, data = ArthT, main = "Tratamiento") # Gráfico tratamiento

Gráficos de Déficit/Superávit

Éstos son esencialmente útiles cuando trabajamos con datos macroeconómicos, series de tiempo, etc. Principalmente podemos encontrarlos en gráficas de balanza comercial, gasto público y todos aquellos que tienen una hoja de balance. Por ejemplo: Imaginemos que queremos graficar datos sobre la balanza comercial de México en los últimos 10 años, siendo que hubo ocasiones en las que ésta fue negativa (cuando hubo más importaciones que exportaciones) y otras en las que fue positiva (cuando hubo más exportaciones que importaciones). Una buena forma de comparar las variaciones de la balanza comercial o su valor neto es con éste tipo de gráficos. Veamos un ejemplo con datos obtenidos de BANXICO sobre la balanza de pagos de los últimos 10 años para el caso de México. Como siempre, comenzamos por cargar y leer los datos, para saber qué estamos trabajando exactamente:

# Cargamos la base
balanza <- read_excel("/Users/jorge/Downloads/balanza.xlsx")

# Leemos la base 
attach(balanza)
head(balanza)
## # A tibble: 6 x 5
##   Fecha               `Cuenta corrien… `Cuenta de capi… `Cuenta financi…
##   <dttm>                         <dbl>            <dbl>            <dbl>
## 1 2010-01-01 00:00:00            -195.            -48.4           -8251.
## 2 2010-04-01 00:00:00             325.            -42.4           -5675.
## 3 2010-07-01 00:00:00            -264.            -30.1           -3338.
## 4 2010-10-01 00:00:00           -4696.            -46.4          -10615.
## 5 2011-01-01 00:00:00           -2404.            -64.7           -9791.
## 6 2011-04-01 00:00:00           -2214.            -73.1          -12772.
## # … with 1 more variable: `Errores y omisiones` <dbl>

Como sabemos, la balanza de pagos es igual a la suma de la cuenta corriente más la cuenta de capital más la cuenta financiera (más los errores cometidos), por lo que vamos a crear otra columna con ésta suma:

balanza_suma <- mutate(balanza, 
                       "Balanza de pagos" = 
                         `Cuenta de capital`+ 
                         `Cuenta corriente`+ 
                         `Cuenta financiera`+ 
                         `Errores y omisiones`)

head(balanza_suma)
## # A tibble: 6 x 6
##   Fecha               `Cuenta corrien… `Cuenta de capi… `Cuenta financi…
##   <dttm>                         <dbl>            <dbl>            <dbl>
## 1 2010-01-01 00:00:00            -195.            -48.4           -8251.
## 2 2010-04-01 00:00:00             325.            -42.4           -5675.
## 3 2010-07-01 00:00:00            -264.            -30.1           -3338.
## 4 2010-10-01 00:00:00           -4696.            -46.4          -10615.
## 5 2011-01-01 00:00:00           -2404.            -64.7           -9791.
## 6 2011-04-01 00:00:00           -2214.            -73.1          -12772.
## # … with 2 more variables: `Errores y omisiones` <dbl>, `Balanza de
## #   pagos` <dbl>

Ahora procedemos a crear el gráfico:

ggplot(balanza_suma, aes( x = Fecha, y = `Balanza de pagos`) ) + 
  geom_area() +
  #geom_point(size = 1.0, color = "darkblue") + 
  theme_bw() + 
  theme(legend.position = "none") +
  theme(legend.title = element_blank()) +
  guides(col = guide_legend(nrow = 1, byrow = TRUE)) + 
  xlab("Periodo") + 
  ylab("Valor")+ 
  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 = "Balanza comercial en México",
    subtitle = "Un ejemplo de gráficos de déficit/superávit.",
    caption = "Fuente: Elaboración propia con datos de BANXICO. \nNotas: Espero que te sea útil."
  )

De igual forma en éste caso tenemos la posibilidad de crear un gráfico interactivo con echarts4r de la siguiente manera:

balanza_suma %>% 
  e_charts(x = Fecha) %>% 
  e_datazoom(
    type = "slider", 
    toolbox = FALSE,
    bottom = -5
  ) %>% 
  e_tooltip() %>% 
  e_title("Balanza comercial de México", "Un ejemplo práctico") %>% 
  e_x_axis(Fecha, axisPointer = list(show = TRUE)) %>% 
  e_area(`Balanza de pagos`) %>% 
  e_axis_labels(x = "Periodo")

Como podemos observar, éste tipo de gráficos suelen ser bastante útiles para comparar valores negativos con valores positivos en ciertos periodos de tiempo, ya que incluso nos muestran la magnitud de éstos valores.

Referencias

  1. 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

  2. Tin Seong, K. (2019). Hands-On Exercise 8: Diverging Stacked Bar Chart. 5 de marzo de 2020, de Rpubs Sitio web: https://rpubs.com/tskam/likert

  3. University of Iowa. (2018). More on Categorical Data. 5 de marzo de 2021, de Statistics & Actuarial Science Sitio web: https://homepage.divms.uiowa.edu/~luke/classes/STAT4580/morecat.html