Presentación

Esta publicación tiene dos objetivos, uno personal y otro general. El objetivo personal es recolectar en un solo archivo todo lo que he aprendido sobre gráficos utilizando el paquete ggplot2; por lo que este script es la recopilación de todos los códigos y comandos que he aprendido hasta ahora. El segundo objetivo, el general, es simplemente compartirlo a todo aquel que guste.

No hay comando en este script que no se encuentre en sitios y foros como stackoverflow, repositorios de github, rpubs, los manuales de Wickham, The R graph gallery, etc.

Aviso: En este documento solo se pretende exponer comandos relacionados con la elaboración de gráficas, así que en lo general, los dataframe necesarios ya fueron trabajados y se encuentran disponibles en mi drive para poder recrear todos los gráficos siguientes. (Si no abre el vínculo con click izquierdo intenta usar click derecho y abrir en otra pestaña).

Cualquier corrección o comentario házmelo saber por este medio o a través de mi twitter ecodiegoale.

Preparación y Paquetes

Preparamos el directorio de trabajo.

#setwd("C:/Users/Diego Alejandro/Documents/R_for_me")

rm(list = ls()) #para borrar todos los objetos en la memoria de la consola
options(scipen=999) #para desactivar la notación científica

Ahora los paquetes.

library(ggplot2)
library(tidyverse)
library(scales)
library(lemon)
library(grid)
library(gridExtra)
library(ggrepel)

Bases de datos necesarias.

tiie_cetes<-read.csv("cetes_tiie.csv", sep = ",", header = TRUE)

pobreza<-read.csv("pobreza.csv", sep = ",", header = TRUE)

salud<-read.csv("derechohabiencia.csv", sep = ",", header = TRUE)

censos<-read.csv("censo.csv", sep = ",", header = TRUE)

pib_sec<-read.csv("pib_sector.csv", sep=",", header = TRUE)

pib_tc<-read.csv("tc_pib.csv", sep = ",", header = TRUE)

promedio <- read.csv("precio_promedio.csv", sep=",", header=TRUE)

pib_mundial<-read.csv("pib_mundial.csv", sep = ",", header = TRUE)

infla<-read.csv("inflacion.csv", sep = ",", header = TRUE)

ingpib<-read.csv("ing_eg_pib.csv", sep = ",", header = TRUE)

expos<-read.csv("expo_mex.csv", sep = ",", header = TRUE)

ginipib<-read.csv("gini_pibpc.csv", sep=",", header = TRUE)

gas<-read.csv("Gas.csv", header = TRUE, sep = ",")

Hasta el momento, elijo manualmente los colores que deseo para mis gráficos, por lo que hago una pequeña tabla con los colores que deseo y su correspondiente código de color en html. Si deseas elegir colores a tu gusto puedes hacerlo en el siguiente enlace:

https://htmlcolors.com/

Podremos llamar este dataframe cada que deseemos recordar el código de los colores.

html_col<-c("#084714", "#00AFBB", "#E7B800", "#FC4E07", "#F349DC", "#F91C09", "#4D05AC")
desc_col<-c("verde","azul","amarillo", "naranja", "rosa", "rojo", "violeta")
colores<-data.frame(html_col, desc_col)
colores
##   html_col desc_col
## 1  #084714    verde
## 2  #00AFBB     azul
## 3  #E7B800 amarillo
## 4  #FC4E07  naranja
## 5  #F349DC     rosa
## 6  #F91C09     rojo
## 7  #4D05AC  violeta

Gráfico de barras

Los gráficos de este tipo, así como los de líneas y puntos ayudan a los lectores a comparar valores a través de distintas categorías. Los gráficos de barras son el tipo de visualización de datos con la que la mayoría de la gente está familiarizada.

Gráfico de barras sencillo

A continuación elaboraremos un gráfico de barras, el más sencillo posible, sobre la tasa porcentual de Cetes 28 días (%) del 2000 al 2018 para México.

Para esto, utilizaremos la base de datos tiie_cetes.

#siempre es buena idea ver cómo se acomodan las variables y observaciones a través de las filas y columnas
head(tiie_cetes)
##    Año      tiie cetes_28
## 1 2000 16.958333 15.24417
## 2 2001 12.885833 11.30583
## 3 2002  8.167500  7.08500
## 4 2003  6.830833  6.22500
## 5 2004  7.145833  6.81500
## 6 2005  7.164868  9.20250

Este es un gráfico de barras predeterminado en ggplot2:

cetes_plot<-ggplot(data=tiie_cetes, aes(y=cetes_28, x=Año))+
        geom_bar(stat="identity")
cetes_plot

Ahora vamos a darle un poco más de formato, añadiendo nombre a los ejes, título, subtítulo, color y nota al pie del gráfico:

cetes_plot<-ggplot(data=tiie_cetes, aes(y=cetes_28, x=Año))+
        geom_bar(stat="identity",color ="#084714", fill="#084714")+
        #el área (fill) y perímetro (color) del gráfico serán verde, que es #084714 en HTML 
        theme(plot.caption=element_text(hjust=0,size=9),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              plot.subtitle =element_text(hjust=0.5, size=12,face="bold"))+
        #plot.caption() es para modificar las notas al pie del gráfico
        #plot.subtitle() es para modificar el subtítulo
        #plot.title() es para modificar el título
        #hjust indica la alineación del texto. 0 es izquierda, 0.5 centrada y 1 a la derecha
        labs(title="Cetes a 28 días",
             subtitle = "2000-2018",
             caption="Fuente: Elaboración propia con información del Banco de México.")+
             xlab("Años")+
             ylab("Puntos porcentuales")
        
cetes_plot

Por último, este gráfico se puede mejorar un poco más. Vamos a añadir el año correspondiente abajo de cada barra y por encima el valor que representa:

cetes_plot<-ggplot(data=tiie_cetes, aes(y=cetes_28, x=Año, colour = cetes_28))+
        #observar que he agregado una nueva instrucción "color = cetes_28
        #esta instrucción se utilizar para etiquetar cada barra con su valor
        #utilizamos la variable cetes_28, la misma que el eje Y
        geom_bar(stat="identity",color ="#084714", fill="#084714")+
        theme(plot.caption=element_text(hjust=0,size=9),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              plot.subtitle =element_text(hjust=0.5, size=12,face="bold"),
              axis.text.x=element_text(angle =45,vjust =1, hjust=1))+
        #con axis.text.x vamos a modificar las etiquetas del eje X
        #con vjust=0 indico la distancia a la que estará la nota del gráfico
        # vjust=1 es lejos, vjust=0 amontonará el eje X con las notas
        #Con "angle" indicamos el grado de inclinación del texto, yo elegí 45
        #hjust=1 junta las etiquetas de años con del eje X
        labs(title="Cetes a 28 días",
             subtitle = "2000-2018",
             caption="Fuente: Elaboración propia con información del Banco de México.")+
             xlab("Año")+
             ylab("Puntos porcentuales")+
        scale_x_continuous(breaks=c(2000,2001,2002,2003,2004,2005,
                                    2006,2007,2008,2009,2010,2011,
                                    2012,2013,2014,2015,2016,2017,2018))+
        #con scale_x_continuous() damos la instrucción de mostrar cada elemento del eje X
        #definimos de 2000 a 2018 pues son los años que comprende 
        #con la instrucción geom_text() añadimos los datos a las barras
        geom_text(aes(label=round(cetes_28,2)), #redondeamos a 2 decimales cetes_28
                        hjust = 0.5, #alineamos al centro
                        size= 3, #tamaño de las etiquetas
                        vjust = -0.5, #distancia de las barras
                        color ="black") #color de la letra

cetes_plot

Gráfico de barras agrupadas

Para esta sección utilizaremos datos sobre la pobreza en México. La base usada es pobreza, definida al inicio de esta publicación.

Se presenta a la proporción de la población que vive en pobreza respecto del total nacional.

Visualicemos los datos necesarios.

head(pobreza)
##   anio     Pobreza    valor
## 1 1992 Alimentaria 21.38000
## 2 1994 Alimentaria 21.17000
## 3 1996 Alimentaria 37.39000
## 4 1998 Alimentaria 33.26000
## 5 2000 Alimentaria 24.12980
## 6 2002 Alimentaria 19.96915

¿Qué valores tiene nuestra variable de interés?

unique(pobreza$Pobreza)
## [1] "Alimentaria" "Total"

Tenemos dos tipos de pobreza: total y alimentaria. Queremos visualizar ambas variables juntas en un mismo gráfico de barras.

El gráfico predeterminado luce de la siguiente manera:

mx_pobreza<-ggplot(pobreza, mapping = aes(anio, valor, fill = Pobreza))+
        #fill será utilizado para rellenar las barras de acuerdo a los dos tipos de Pobreza
        geom_bar(position="dodge", stat = "identity")
mx_pobreza

Comencemos el diseño:

mx_pobreza<-ggplot(pobreza, mapping = aes(anio, valor, fill = Pobreza))+
        geom_bar(position="dodge", stat = "identity",color="black")+
        theme(legend.position = "bottom")+
        #con legend.position elegimos la posición de las leyendas
        scale_fill_manual(values = c("#00AFBB","#E7B800"))+
        #scale_fill_manual () para rellenar las barras con los colores deseados
        xlab("Años")+
        ylab("% de la población")
        
mx_pobreza

Ya tenemos los colores deseados y los nombres de cada eje. Podemos dar un diseño completo como con el gráfico de Cetes.

Para este gráfico nuevamente utilizaremos la instrucción scale_x_continuous(), pero para evitar la tediosa tarea de copiar uno a uno los años correspondientes, lo haremos de una manera más rápida:

Definiremos un nuevo objeto de la siguiente forma:

anios_pobr<-c(pobreza$anio)

pobreza es la base de datos, al utilizar el operador $ damos la instrucción que solo queremos extraer el vector anio, donde están todos los años.

mx_pobreza<-ggplot(pobreza, mapping = aes(anio, valor, fill = Pobreza))+
        geom_bar(position="dodge", stat = "identity",color="black")+
        theme(legend.position = "bottom",
              plot.caption=element_text(hjust=0,size=8),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              plot.subtitle =element_text(hjust=0.5, size=12,face="bold"),
              axis.text.x=element_text(angle =45,vjust =1, hjust=1))+
        scale_fill_manual(values = c("#00AFBB","#E7B800"))+
        labs(title="Evolución de la pobreza en México",
             subtitle = "Total y alimentaria, 1992-2018",
             caption="Nota: A partir del 2008, los porcentajes de pobreza alimentaria corresponden a la medición de la pobreza multidimensional,
la nueva metodología del CONEVAL y hasta 2008, los porcentajes de pobreza son los relativos a la pobreza patrimonial,
medida correspondiente a la anterior metodología de medición de la pobreza del CONEVAL.

Fuente: Elaboración propia con información de CONEVAL.")+
        xlab("Años")+
        ylab("% de la población")+
        scale_x_continuous(breaks=anios_pobr)#aquí está el vector que creamos

mx_pobreza

Paquete scales

Por último, ofrecemos otro ejemplo de gráfico de barras agrupadas, con otros comandos e instrucciones importantes para el diseño y presentación de gráficos de alta calidad.

Explorando la base de datos salud observamos que tenemos información sobre la derechohabiencia en México por sexo y de 2000 a 2020.

names(salud)
## [1] "anio"             "Derechohabiencia" "Sexo"             "Valor"
unique(salud$anio)
## [1] 2000 2005 2010 2020
unique(salud$Derechohabiencia)
## [1] "Sin derechohabiencia" "Con derechohabiencia" "Sin especificar"     
## [4] "Con afiliación"       "Sin afiliación"

Para el siguiente gráfico solo requerimos el año 2020, por lo que filtramos la base utilizando la función filter del paquete tidyverse:

salud2020<-salud%>%
        filter(anio==2020)

Una vez filtrada podemos hacer el gráfico:

salud20<-ggplot(data=salud2020, aes(fill=Sexo, y=Valor, x=Derechohabiencia))+
        geom_bar(position="dodge", stat="identity")+
        scale_fill_manual(values=c("#00AFBB", "#FC4E07"))+
        theme(axis.text.x=element_text(angle = 0, vjust = 1, hjust=0.5),
              plot.caption=element_text(hjust=0,size=8),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              plot.subtitle =element_text(hjust=0.5, size=12,face="bold"),
              legend.position = c(0.9, 0.8))+
        #podemos poner la leyenda del gráfico dentro del gráfico, definiendo valores del 0 al 1
        ylab("Miles de personas")+
        xlab("")+
        labs(title="Afiliación a servicios de salud",
             subtitle = "Año 2020",
             caption="Fuente: Elaboración propia con información del Censo de población y vivienda 2020, INEGI.")+
        geom_text(aes(label = round(Valor, 1)),
                  size = 3, hjust = 0.5, 
                  vjust = -0.5)
salud20

Utilizar el código que hemos venido usando para poner etiquetas de datos sobre las barras en un gráfico que es de barras agrupadas no resulta oportuno, necesitamos las etiquetas de datos sobre su correspondiente barra. Además, al tener los valores con más de tres ceros puede resultar díficil de leer para algunos, por lo que separar con comas también es necesario.

salud20<-ggplot(data=salud2020, aes(fill=Sexo, y=Valor, x=Derechohabiencia))+
        geom_bar(position="dodge", stat="identity")+
        scale_fill_manual(values=c("#00AFBB", "#FC4E07"))+
        theme(axis.text.x=element_text(angle = 0, vjust = 1, hjust=0.5),
              plot.caption=element_text(vjust = 1,hjust=0,size=8),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              plot.subtitle =element_text(hjust=0.5, size=12,face="bold"),
              legend.position = c(0.9, 0.8))+
        ylab("Miles de personas")+
        xlab("")+
        labs(title="Afiliación a servicios de salud",
             subtitle = "Año 2020",
             caption="Fuente: Elaboración propia con información del Censo de Población y Vivienda 2020, INEGI.")+
        scale_y_continuous(label=comma, limits = c(0,50000) )+
        #scale_y_continuous() define los límites del eje Y. Yo escogí de 0 a 50,000
        #además de que agregué separadores de miles utilizando label=comma
        geom_text(aes(label = scales::comma(round(Valor, 1))),
                  #utilizando el paquete SCALES agregamos las comas a las etiquetas del gráfico
                  size = 3, hjust = 0.5, 
                  vjust = -0.5,
                  position = position_dodge(width = 1))
                #con position_dodge(width = 1) definimos que los valores estarán sobre su barra
                #si fuera width = 0 las etiquetas estarían apiladas como en el anterior
salud20

Ahora tenemos un gráfico que muestra separación de miles tanto en sus ejes como en las etiquetas de sus datos.

Gráfico de barras apiladas

“El gráfico de barras apiladas representa la magnitud con que se expresa el resultado del análisis de un todo, por medio del estudio de sus cualidades, características o atributos propios sobre el objeto de la investigación.”

Fuente: ¿Qué es un gráfico de barras apiladas? https://graficodebarras.com/que-es-un-grafico-de-barras-apiladas

Para ejemplificar este tipo de gráfico utilizaremos la base pib_sec, la cual contiene la información del Producto Interno Bruto (PIB) de México por tipo de actividad económica.

names(pib_sec) #exploramos las variables que contiene
## [1] "año"    "valor"  "Sector"
anios_pib_sec<-c(pib_sec$año) #definimos el vector con los años, esto para el eje X

En su versión más simple, así luce este tipo de gráfico con las variables seleccionadas.

sectores<-ggplot(data=pib_sec, aes(x=año, y=valor, fill=Sector))+
        geom_bar(stat="identity",size=1)
#notar que ya no agregamos position="dodge" como en los gráficos de barras agrupadas
sectores

Como es costumbre, procedemos a rediseñar nuestro gráfico:

sectores<-ggplot(data=pib_sec, aes(x=año, y=valor, fill=Sector))+
        geom_bar(stat="identity",size=1)+
        scale_fill_manual(values = c("#FC4E07", "#E7B800", "#00AFBB"))+
        theme(axis.text.x=element_text(angle = 45, vjust = 1, hjust=1),
              plot.caption=element_text(vjust = 1,hjust=0,size=8),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              plot.subtitle =element_text(hjust=0.5, size=12,face="bold"),
              legend.position = "right")+
        scale_x_continuous(breaks=anios_pib_sec)+
        labs(x = " ",
             y = "Porcentaje del PIB",
             title = "PIB por tipo de actividad económica",
             subtitle = "2000-2018",
             caption="Fuente: Banco de Información Económica, INEGI.")


sectores

A continuación agregaremos las etiquetas de datos correspondientes.

A diferencia del gráfico Afiliación de servicios de salud, en la instrucción position de la función geom_text() escribimos position_stack en lugar de position_dodge

sectores<-ggplot(data=pib_sec, aes(x=año, y=valor, fill=Sector))+
        geom_bar(stat="identity",size=1)+
        scale_fill_manual(values = c("#FC4E07", "#E7B800", "#00AFBB"))+
        theme(axis.text.x=element_text(angle = 45, vjust = 1, hjust=1),
              plot.caption=element_text(vjust = 1,hjust=0,size=8),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              plot.subtitle =element_text(hjust=0.5, size=12,face="bold"),
              legend.position = "right")+
        scale_x_continuous(breaks=anios_pib_sec)+
        labs(x = " ",
             y = "Porcentaje del PIB",
             title = "PIB por tipo de actividad económica",
             subtitle = "2000-2018",
             caption="Fuente: Banco de Información Económica, INEGI.")+
        geom_text(aes(label = round(valor, 2)),
                  size = 2, hjust = 0.5, 
                  position = position_stack(vjust = 0.5))
                #poner atención en la instrucción position


sectores

Gráfico de barras con valores negativos

Este tipo de gráficos es un gráfico de barras simple, únicamente aprovechamos para introducir tres instrucciones nuevas.

Para ilustrar este tipo de gráfico, usaremos la base pib_tc, la cual contiene la tasa de crecimiento simple del PIB de México para el periodo 2000-2018.

Primero, definimos el vector de los años, para facilitar la elaboración del eje X.

anios_pib_tc<-pib_tc$año

Las nuevas instrucciones son alpha de la función geom_bar(),seq() para agilizar la definición del eje Y y geom_hline().

alpha sirve para dar transparencia al color del área.

seq() generará una secuencia con las condiciones que definamos.

geom_hline() para remarcar la intersección con 0.

pibtc_y<-seq(-5,6, by=1) #una secuencia que va de -5 hasta 6 de uno en uno

Una vez hecho esto podemos graficar.

tc<-ggplot(data=pib_tc, aes(x=año, y=Crecimiento))+
        geom_bar(stat="identity",color="black", fill="#FC4E07", size=1, alpha=0.8)+
        scale_x_continuous(breaks=anios_pib_tc)+
        theme(axis.text.x=element_text(angle = 45, vjust = 1, hjust=1),
              plot.caption=element_text(vjust = 1,hjust=0,size=8),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              plot.subtitle =element_text(hjust=0.5, size=12,face="bold"))+
        labs(x = " ",
             y = "Puntos porcentuales",
             title = "Tasa de crecimiento del PIB",
             subtitle = "2000-2018",
             caption="Fuente: Banco de Información Económica, INEGI.")+
        geom_hline(yintercept = 0, size=1)+
        #dibujamos la línea que pasa sobre el 0 en todo el eje Y
        scale_y_continuous(breaks=pibtc_y)
        #aquí utilizamos la secuencia que hicimos

tc

Gráfico de barras horizontales

En ese apartado se presenta cómo elaborar un gráfico de barras con orientación horizontal; esto puede resultar ventajoso cuando las observaciones presentan nombres un poco largos o simplemente porque se desea que sea horizontal.

Además, como un extra, agregamos la opción de colorear una observación de un colo diferente al resto.

Para esto utilizaremos las siguientes funciones e instrucciones:

  1. factor() y ifelse()
  2. scale_fill_manual()
  3. coord_flip()
  4. nudge_x

La base de datos que usaremos en este ejercicio se denomina promedio, la cual contiene el precio promedio de servicios de guardería para diferentes ciudades del Norte de México. Como siempre, recomendamos explorarla antes.

head(promedio)
##             Entidad Precio_promedio
## 1  Cd. Acuña, Coah.        2264.165
## 2 Cd. Juárez, Chih.        2627.082
## 3  Chihuahua, Chih.        2688.645
## 4    Culiacán, Sin.        3145.832
## 5     Durango, Dgo.        2558.023
## 6   Esperanza, Son.        1661.457
glimpse(promedio)
## Rows: 19
## Columns: 2
## $ Entidad         <chr> "Cd. Acuña, Coah.", "Cd. Juárez, Chih.", "Chihuahua...
## $ Precio_promedio <dbl> 2264.165, 2627.082, 2688.645, 3145.832, 2558.023, 1...

Nuestra base contiene 19 observaciones y 2 variables (Entidad y Precio_Promedio)

Con factor() y ifelse() establecemos la condición lógica: Si la columna Entidad (que contiene el nombre de las ciudades) es igual a “Total nacional”, que es la observación que nos interesa resaltar con un color diferente, entonces las observaciones que coincidan con dicha proposición serán agrupadas en un grupo, un grupo que denomino ; en este caso, dentro de Sí solo habrá una observación, pues no hay más de un “Total nacional” en toda la base. Para las observaciones que no cumplan el criterio, estas serán agrupadas en No.

Utilizando scale_fill_manual() definimos los colores que queremos. Rojo para el Total nacional y amarillo para el resto.

Usando nudge_x con el resto de instrucciones de geom_text() agregamos las etiquetas de datos dentro de las barras y alineadas a la izquierda.

promedio_plot<-ggplot(promedio, aes(
        x=Entidad, y=Precio_promedio,
        #utilizando factor() y ifelse() definimos la condición para 
        #únicamente colorear la barra de Total nacional
        fill=factor(ifelse(Entidad=="Total nacional","Sí","No")))) + 
        geom_bar(stat = "identity", width=0.8,
                 color="black",size=0.5,alpha=0.8) +
        coord_flip()+ #con coord_flip() lo volvemos horizontal
        theme(axis.text.x=element_text(vjust = 1, hjust=1),
              plot.caption=element_text(vjust = 1,hjust=0,size=8),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              plot.subtitle =element_text(hjust=0.5, size=12,face="bold"))+
        scale_fill_manual(name = "Entidad", values=c("#E7B800","#F91C09"))+
        #con scale_fill_manual() elegimos el color de la columna seleccionada
        #y el del resto 
         labs(y = " ", x= "Pesos",
             title = "Precios promedio mensuales de servicios de guardería",
             subtitle = "Ciudades del norte de México, 2021",
             caption="Fuente: Elaboración propia con información del INPC, INEGI.")+
        xlab(" ")+
        ylab("Pesos")+
        scale_y_continuous(label=comma)+
        geom_text(aes(label = scales::comma(round(Precio_promedio,-1))),
                  #hacer que las etiquetas estén alineadas a la izquierda
                  #y dentro de las barras
                  size = 3, hjust = 1, nudge_x = -0.5, vjust=-0.5)

promedio_plot

Por último, necesitamos remover esa leyenda innecesaria que únicamente utilizamos para diferenciar las barras con los colores elegidos. Para esto usamos la instrucción legend.position="none" de la función theme():

promedio_plot<-ggplot(promedio, aes(
        x=Entidad, y=Precio_promedio,
        fill=factor(ifelse(Entidad=="Total nacional","Sí","No")))) + 
        geom_bar(stat = "identity", width=0.8,
                 color="black",size=0.5,alpha=0.8) +
        coord_flip()+
        theme(axis.text.x=element_text(vjust = 1, hjust=1),
              legend.position="none", #borramos la leyenda innecesaria
              plot.caption=element_text(vjust = 1,hjust=0,size=8),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              plot.subtitle =element_text(hjust=0.5, size=12,face="bold"))+
        scale_fill_manual(name = "Entidad", values=c("#E7B800","#F91C09"))+
        labs(y = " ", x= "Pesos",
             title = "Precios promedio mensuales de servicios de guardería",
             subtitle = "Ciudades del norte de México, 2021",
             caption="Fuente: Elaboración propia con información del INPC, INEGI.")+
        xlab(" ")+
        ylab("Pesos")+
        scale_y_continuous(label=comma)+
        geom_text(aes(label = scales::comma(round(Precio_promedio,-1))),
                  size = 3, hjust = 1, nudge_x = -0.5, vjust=-0.5)

promedio_plot

Pirámides poblacionales

“La pirámide de población o pirámide demográfica es un histograma o gráficos. Es de barras dispuestas horizontalmente cuya longitud es proporcional a la cantidad de personas que representa la edad y sexo de la población en cada una de dichas barras y dicha información sirve para saber el porcentaje de la población.”

-Wikipedia

Para esta sección utilizaremos la base censo. Como siempre, recomiendo explorar la base de datos.

Esta base presenta información de los censos 2000, 2010 y 2020. Los datos son el número de habitantes por sexo.

Haremos la pirámide del año 2020.

Primero, filtramos la base de censos, para solo tener los datos del año 2020:

censo2020<-censos%>%
        filter(anio==2020)

Segundo, creo el vector de edades que corresponden al censo 2020, después lo junto todo en un solo daraframe:

censo_ed_20<-c("05-09","10-14","15-19","20-24","25-29",
        "30-34","35-39","40-44","45-49","50-54",
        "55-59","60-64","65-69","70-74","75-79",
        "80-84","85 y más")

censo20<-cbind(censo_ed_20,censo2020) #junto el vector de edades con el censo filtrado

censo20_miles<-censo20%>%mutate(valores_miles=round(Valores/1000))
#usando tidyverse creamos una variable nueva (valores_miles), que serán los habitantes en miles de personas

head(censo20_miles)
##   censo_ed_20 anio   Sexo Valores valores_miles
## 1       05-09 2020 Hombre 5453091          5453
## 2       10-14 2020 Hombre 5554260          5554
## 3       15-19 2020 Hombre 5462150          5462
## 4       20-24 2020 Hombre 5165884          5166
## 5       25-29 2020 Hombre 4861404          4861
## 6       30-34 2020 Hombre 4527726          4528

Una vez con el dataframe correcto podemos empezar a graficar.

El eje X tiene una prueba lógica, si la variable Sexo es igual a Hombre, todos los valores serán negativos, si es diferente serán positivos (este será el caso para Mujer)

pp20<-ggplot(data=censo20_miles,
             mapping = aes(
                     x=ifelse(test=Sexo == "Hombre", yes = -valores_miles, no =valores_miles),
                     y=censo_ed_20, fill = Sexo)) +
        geom_col()+
        scale_x_symmetric(labels = abs)
        #la función scale_x_symmetric() es del paquete LEMON.

pp20

Procedemos a darle un mejor diseño a este gráfico:

pp20<-ggplot(data=censo20_miles,
             mapping = aes(
                     x=ifelse(test = Sexo == "Hombre", yes = -valores_miles, no =valores_miles),
                     y=censo_ed_20, fill = Sexo)) +
        geom_col()+
        theme(plot.caption=element_text(vjust = 1,hjust=0,size=8),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              plot.subtitle =element_text(hjust=0.5, size=12,face="bold"))+
        scale_fill_manual(values = c("#00AFBB","#FC4E07"))+
        scale_x_symmetric(labels = abs) +
        ylab("Edades")+
        xlab("Miles de personas")+
        labs(title="Pirámide poblacional",
             subtitle = "Año 2020",
             caption="Fuente: Elaboración propia con información del Censo de Población y Vivienda 2020, INEGI.")

pp20

Gráfico de líneas

“Los gráficos de líneas y de barras son los gráficos más conocidos en todo el mundo. El gráfico de líneas es fácil de leer, su representación es clara y es fácilmente de dibujar con lápiz y papel. Los valores de los datos están conectados por líneas para mostrar los valores a lo largo de un periodo continuo, mostrando las tendencias y sus patrones”

-Jonathan Schwabish.Better data visualizations: A guide for Scholars, Researchers, and Wonks (traducción propia)

Gráfico de líneas simple

A continuación se elaborará un gráfico de líneas sencillo, donde únicamente se mostrará una sola serie de datos. Para este caso, graficaremos una proyección del PIB mundial, el cual está contenido en la base pib_mundial.

Como es costumbre, hay que explorar la base.

glimpse(pib_mundial)
## Rows: 47
## Columns: 4
## $ Año                     <int> 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1...
## $ PIBmundial              <dbl> 2.083, 1.884, 0.481, 2.704, 4.533, 3.585, 3...
## $ PIBavanzadas            <dbl> 1.335, 2.011, 0.233, 3.183, 4.861, 3.715, 3...
## $ PIBeconomías.emergentes <dbl> 3.318, 1.668, 0.903, 1.876, 3.961, 3.358, 4...
names(pib_mundial)
## [1] "Año"                     "PIBmundial"             
## [3] "PIBavanzadas"            "PIBeconomías.emergentes"

Tenemos una base con 47 observaciones, que son los años, y tres variables: PIBmundial, PIBAvanzadas y PIBeconomías.emergentes. La primera muestra la serie del PIB mundial y sus proyecciones para todo el mundo, la segunda contiene el PIB de las economías avanzadas, la tercera de las economías emergentes, esto con la definición del Fondo Monetario Internacional.

pib_growth<-ggplot(data=pib_mundial, aes(x=Año))+
        geom_line(aes(y=PIBmundial))
 #La función geom_line() es la apropiada para este tipo de gráficos
pib_growth

Una vez reconocida la estructura básica del gráfico de líneas podemos darle una mejor presentación con las funciones que hemos aprendido hasta ahorita:

pib_fmi<-seq(1980,2026, by=2) #creamos la secuencia para los años del eje X
pib_growth<-ggplot(data=pib_mundial, aes(x=Año))+
        geom_line(aes(y=PIBmundial), linetype = 'dashed', colour="#00AFBB", cex = 1.0)+
        theme(plot.caption=element_text(hjust=0,size=9),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              plot.subtitle =element_text(hjust=0.5, size=12,face="bold"),
              axis.text.x=element_text(angle =45,vjust =1, hjust=1))+
        geom_hline(yintercept = 0, size=1)+
        labs(title="Pronósticos del PIB Mundial",
             subtitle = "1980-2026",
             caption="Fuente: World Economic Outlook Database, IMF.")+
             xlab("Años")+
             ylab("Puntos porcentuales")+
        scale_x_continuous(breaks=pib_fmi)
pib_growth

La nuevas instrucciones que agregamos son cex para definir el grueso de la línea y linetype para seleccionar el tipo de línea que queremos que se muestre, en este caso utilizamos dashed, para una línea discontinua. Los tipos de líneas disponibles son: “blank”, “solid”, “dashed”, “dotted”, “dotdash”, “longdash”, “twodash”. Puedes probar cada tipo de línea y explorar cómo lucen.

Gráfico de líneas múltiples

¿Qué sucede cuando queremos mostrar diferentes series con la misma escala y pertinencia en el mismo gráfico de líneas?

En la base anterior, observamos que están disponibles las series del PIB para el mundo, para los países de economías avanzadas y de economías emergentes. Vamos a crear un gráfico con las tres series juntas.

pib_fmi_yaxis<-seq(-5,9, by=1)#definimos una nueva secuencia para el eje Y
pib_growth<-ggplot(data=pib_mundial, aes(x=Año))+
        geom_line(aes(y=PIBmundial), cex = 1.0)+
        geom_line(aes(y=PIBavanzadas), cex = 1)+
        geom_line(aes(y=PIBeconomías.emergentes) ,cex = 1)+
        theme(plot.caption=element_text(hjust=0,size=9),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              plot.subtitle =element_text(hjust=0.5, size=12,face="bold"),
              axis.text.x=element_text(angle =45,vjust =1, hjust=1))+
        geom_hline(yintercept = 0, size=1)+
        labs(title="Pronósticos del PIB Mundial",
             subtitle = "1980-2026",
             caption="Fuente: World Economic Outlook Database, IMF.")+
             xlab("Años")+
             ylab("Puntos porcentuales")+
        scale_x_continuous(breaks = pib_fmi)+
        scale_y_continuous(breaks = pib_fmi_yaxis)

pib_growth

Este gráfico tiene dos problemas: no hay distinción visual entre las series y tampoco hay leyendas para cada serie. Vamos a solucionar este problema.

Para cada función geom_line() donde se define un eje Y diferente para cada serie, con la instrucción color= vamos a poner el nombre que queremos que se muestre en la leyenda.

Después, para diferenciar cada línea con un color distinto utilizamos la función scale_color_manual(). A diferencia de scale_fill_manual() que usamos para el gráfico de barras horizontales, en name = no agregamos el nombre de la columna que contiene las observaciones, pues ahora, para esta base de datos, cada serie está una columna diferente, por lo que se deja vacío, seguido añadimos los valores para los colores deseados.

pib_growth<-ggplot(data=pib_mundial, aes(x=Año))+
        geom_line(aes(y=PIBmundial, color = 'PIB mundial'), cex = 1.0)+
        geom_line(aes(y=PIBavanzadas, color = 'PIB de economías avanzadas'), cex = 1)+
        geom_line(aes(y=PIBeconomías.emergentes, color = 'PIB de economías emergentes'),cex = 1)+
        scale_color_manual(name = " ",values=c("#00AFBB", "#E7B800", "#FC4E07"))+
        #observar la estructura de scale_color_manual()
        geom_hline(yintercept = 0, size=1)+
        theme(plot.caption=element_text(hjust=0,size=9),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              plot.subtitle =element_text(hjust=0.5, size=12,face="bold"),
              axis.text.x=element_text(angle =45,vjust =1, hjust=1),
              legend.position = "bottom")+
        labs(title="Pronósticos del PIB Mundial",
             subtitle = "1980-2026",
             caption="Fuente: World Economic Outlook Database, IMF.")+
             xlab("Años")+
             ylab("Puntos porcentuales")+
        scale_x_continuous(breaks = pib_fmi)+
        scale_y_continuous(breaks = pib_fmi_yaxis)

pib_growth

Gráfico de líneas con etiquetas

En esta sección crearemos un gráfico de líneas sencillo, pero con la particularidad de poner etiquetas de datos. Para esto usaremos la base infla, la cual contiene la información de la inflación subyacente del periodo 2000-2018 para México.

head(infla)
##    Año inflacion
## 1 2000    0.0896
## 2 2001    0.0440
## 3 2002    0.0570
## 4 2003    0.0398
## 5 2004    0.0519
## 6 2005    0.0333

La tasa de inflación se presenta siempre en puntos porcentuales, sin embargo, como acabamos de ver al explorar la base, la inflación se presenta aquí en números decimales.

Primero, necesitamos convertir dichos números decimales en puntos porcentuales, para lo cual manipularemos una nueva variable utilizando tidyverse como sigue:

infla2<-infla%>%mutate(infla_percent=inflacion*100)%>%
        mutate(etiquetas=as.character(infla_percent))
head(infla2)
##    Año inflacion infla_percent etiquetas
## 1 2000    0.0896          8.96      8.96
## 2 2001    0.0440          4.40       4.4
## 3 2002    0.0570          5.70       5.7
## 4 2003    0.0398          3.98      3.98
## 5 2004    0.0519          5.19      5.19
## 6 2005    0.0333          3.33      3.33

Por un lado definimos una nueva variable llamada infla_percent, la cual multiplica por \(100\) todos los valores de la columna inflacion.

Una vez hecho esto necesitamos una nueva variable con la información obtenida en el paso anterior pero ya no en un vector de tipo dbl; necesitamos convertirlo a un vector de caracteres (chr). Para esto usamos la función as.character() para crear el vector de chr al cual he llamado etiquetas.

Una vez hecho esto proseguimos a graficar:

infla_xaxis<-seq(2000,2018, by=1) #creamos la secuencia para el eje X

inflacion_plot<-ggplot(data=infla2, aes(x=Año, y=inflacion, colour = inflacion))+
        geom_line(color="#4D05AC", size=1, linetype= "dotdash")+
        scale_y_continuous(label=percent)+
        #label=percent convierte en % la columna de números decimales
        scale_x_continuous(breaks=infla_xaxis)+
        theme(plot.caption=element_text(hjust=0,size=9),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              plot.subtitle =element_text(hjust=0.5, size=12,face="bold"),
              axis.text.x=element_text(angle =45,vjust =1, hjust=1))+
        labs(title="Tasa de inflación de México",
             subtitle = "2000-2018",
             caption="Fuente: INPC, INEGI (2021).")+
             xlab("Años")+
             ylab("Puntos porcentuales")+
        geom_text(aes(label = etiquetas),
                  size = 3, hjust = 1, 
                  show.legend = FALSE,
                  vjust=-0.5, face="bold",
                  color="black",nudge_x = -0.5)
inflacion_plot

El gráfico anterior está casi completo, sin embargo, algunas de las etiquetas de datos se amontonan, sobre todo en las etiquetas de 2009 al 2015. Necesitamos separarlas, para lo cual utilizaremos la función geom_text_repel() del paquete ggrepel, en lugar de la función geom_text() que hemos venido usando hasta el momento:

inflacion_plot<-ggplot(data=infla2, aes(x=Año, y=inflacion, colour = inflacion))+
        geom_line(color="#4D05AC", size=1, linetype= "dotdash")+
        scale_y_continuous(label=percent)+
        scale_x_continuous(breaks=infla_xaxis)+
        theme(plot.caption=element_text(hjust=0,size=9),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              plot.subtitle =element_text(hjust=0.5, size=12,face="bold"),
              axis.text.x=element_text(angle =45,vjust =1, hjust=1),
              legend.position = "none")+
        labs(title="Tasa de inflación de México",
             subtitle = "2000-2018",
             caption="Fuente: INPC, INEGI (2021).")+
             xlab("Años")+
             ylab("Puntos porcentuales")+
        geom_text_repel(aes(label=etiquetas),
                  hjust = 0.5,
                  show.legend = FALSE,
                  size= 3, vjust = 0.5,
                  color ="black", face="bold",
                  nudge_x = -0.6)
inflacion_plot

Gráfico de líneas con puntos

Este tipo de gráfico es igual al gráfico de líneas simple, con la diferencia de que resalta los marcadores que unen a toda la línea. Pueden ser usados cuando hay pocos puntos en toda la serie.

Nuevamente retomaremos la base infla2. Únicamente agregamos la función geom_point() y definimos el mismo eje y que el utilizado para la línea. Es decisión personal si elegir el mismo color para los marcadores y las líneas.

inflacion_plot<-ggplot(data=infla2, aes(x=Año, y=inflacion, colour = inflacion))+
        geom_line(color="#FC4E07", size=1)+
        geom_point(colour ="#00AFBB", aes(y=inflacion), size=2)+
        #poner atención en geom_point()
        scale_y_continuous(label=percent)+
        scale_x_continuous(breaks=infla_xaxis)+
        theme(plot.caption=element_text(hjust=0,size=9),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              plot.subtitle =element_text(hjust=0.5, size=12,face="bold"),
              axis.text.x=element_text(angle =45,vjust =1, hjust=1),
              legend.position = "none")+
        labs(title="Tasa de inflación de México",
             subtitle = "2000-2018",
             caption="Fuente: INPC, INEGI (2021).")+
             xlab("Años")+
             ylab("Puntos porcentuales")+
        geom_text_repel(aes(label=etiquetas),
                  hjust = 0.5,
                  show.legend = FALSE,
                  size= 3, vjust = 0.5,
                  color ="black", face="bold",
                  nudge_x = -0.6)
inflacion_plot

Gráfico de líneas múltiples con puntos

Por último, si quisieramos realizar un gráfico de líneas múltiples con puntos o marcadores solo tendríamos que combinar lo aprendido en las secciones previas de la manera siguiente:

Para este ejemplo usaremos la base ingpib, la cual contiene los datos de la composición del ingreso presupuestario y del gasto neto total pagado como porcentaje del PIB para México, del periodo 2000-2018.

head(ingpib)
##    año ingresos gasto_neto ingresos_petro ingresos_no_petro ingresos_tribu
## 1 2000     17.6       18.5            4.8              12.8            8.7
## 2 2001     18.0       18.6            4.2              13.7            9.3
## 3 2002     18.6       19.6            4.0              14.6            9.8
## 4 2003     20.3       20.9            5.6              14.7            9.8
## 5 2004     20.1       20.3            6.6              13.4            8.7
## 6 2005     20.4       20.5            7.4              13.0            8.5
##   ingresos_no.tribu gasto_progra gasto_capital gasto_no_progra
## 1               8.9         12.7           2.2             5.8
## 2               8.7         13.1           2.1             5.5
## 3               8.8         14.2           2.7             5.4
## 4              10.6         15.5           2.5             5.5
## 5              11.3         14.9           2.9             5.4
## 6              11.9         15.3           2.9             5.2
names(ingpib)
##  [1] "año"               "ingresos"          "gasto_neto"       
##  [4] "ingresos_petro"    "ingresos_no_petro" "ingresos_tribu"   
##  [7] "ingresos_no.tribu" "gasto_progra"      "gasto_capital"    
## [10] "gasto_no_progra"

Graficamos:

ingpib_plot<-ggplot(data=ingpib, aes(x=año))+
        geom_line(aes(y=ingresos, color = 'Ingresos presupuestarios'),cex = 1)+
                geom_point(colour = "#FC4E07", aes(y=ingresos))+
        geom_line(aes(y=ingresos_petro, color = 'Ingresos petroleros'), cex = 1)+
                geom_point(colour ="#E7B800", aes(y=ingresos_petro))+
        geom_line(aes(y=ingresos_no_petro, color = 'Ingresos no petroleros'),cex = 1)+
                geom_point(colour ="#084714", aes(y=ingresos_no_petro))+
        geom_line(aes(y=ingresos_tribu, color = 'Ingresos tributarios'),cex = 1)+
                geom_point(colour ="#F349DC", aes(y=ingresos_tribu))+
        geom_line(aes(y=ingresos_no.tribu, color = 'Ingresos no tributarios'),cex = 1)+
                geom_point(colour ="#00AFBB", aes(y=ingresos_no.tribu))+
        scale_color_manual(" ",values=c("#084714", "#00AFBB", "#E7B800", "#FC4E07", "#F349DC"))+
        theme(plot.caption=element_text(hjust=0,size=9),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              plot.subtitle =element_text(hjust=0.5, size=12,face="bold"),
              axis.text.x=element_text(angle =45,vjust =1, hjust=1),
              legend.position = "right")+
        labs(title="Composición de los ingresos presupuestarios",
             subtitle = "como porcentaje del PIB (base 2013)",
             caption="Fuente: Secretaría de Hacienda y Crédito Público.")+
             xlab("Años")+
             ylab("Puntos porcentuales")+
        scale_x_continuous(breaks=infla_xaxis)
        #no volveré a hacer otra secuencia de 2000 a 2018


ingpib_plot

Ahora, si lo que quieres es cambiar la forma de los puntos debes usar el argumento shape de la función geom_point(). Son 26 formas básicas, las cuales puedes apreciar en el siguiente link:

http://www.sthda.com/english/wiki/ggplot2-point-shapes

Un ejemplo de las diferentes formas:

ingpib_plot<-ggplot(data=ingpib, aes(x=año))+
        geom_line(aes(y=ingresos, color = 'Ingresos presupuestarios'),cex = 1)+
                geom_point(colour = "#FC4E07", aes(y=ingresos),
                           shape=15, size=2)+
        geom_line(aes(y=ingresos_petro, color = 'Ingresos petroleros'), cex = 1)+
                geom_point(colour ="#E7B800", aes(y=ingresos_petro),
                           shape=17, size=2)+
        geom_line(aes(y=ingresos_no_petro, color = 'Ingresos no petroleros'),cex = 1)+
                geom_point(colour ="#084714", aes(y=ingresos_no_petro),
                           shape=18, size=3)+
        geom_line(aes(y=ingresos_tribu, color = 'Ingresos tributarios'),cex = 1)+
                geom_point(colour ="#F349DC", aes(y=ingresos_tribu),
                           shape=25, size=2, fill="#F349DC")+
        geom_line(aes(y=ingresos_no.tribu, color = 'Ingresos no tributarios'),cex = 1)+
                geom_point(colour ="#00AFBB", aes(y=ingresos_no.tribu),
                           size=2)+
        scale_color_manual(" ",values=c("#084714", "#00AFBB", "#E7B800", "#FC4E07", "#F349DC"))+
        theme(plot.caption=element_text(hjust=0,size=9),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              plot.subtitle =element_text(hjust=0.5, size=12,face="bold"),
              axis.text.x=element_text(angle =45,vjust =1, hjust=1),
              legend.position = "right")+
        labs(title="Composición de los ingresos presupuestarios",
             subtitle = "como porcentaje del PIB (base 2013)",
             caption="Fuente: Secretaría de Hacienda y Crédito Público.")+
             xlab("Años")+
             ylab("Puntos porcentuales")+
        scale_x_continuous(breaks=infla_xaxis)
       
ingpib_plot

Series de tiempo

Hasta el momento, en toda esta sección, hemos estado trabajando con series de tiempo, cuando denomino a esta subsección Series de tiempo lo hago en referencia que ahora el vector de tiempo ya no viene únicamente con un año, ahora viene como una fecha completa, con día, mes y año.

Para esto utilizaremos la base llamada expos, la cual contiene las exportaciones agropecuarias de México en millones de dólares de 2018 a 2020, mes con mes.

glimpse(expos$fecha)
##  chr [1:40] "01/01/2018" "01/02/2018" "01/03/2018" "01/04/2018" ...

Para que R lo reconozca como un vector de fechas y no como uno de caracteres debemos indicarselo de la manera siguiente:

expos$fecha<-as.Date(expos$fecha,"%d/%m/%Y")
#expos es el nombre que le dimos a la base
#fecha es el nombre de la columna que contiene todas las fechas

Utilizando as.Date() indicamos que la columna fecha de la base de datos expos debe ser reconocida como fecha. Como las fechas de la columna vienen en día-mes-año utlizamos “%d/%m/%Y” para que así lo lea.

glimpse(expos$fecha)
##  Date[1:40], format: "2018-01-01" "2018-02-01" "2018-03-01" "2018-04-01" "2018-05-01" ...

Ahora, como podemos ver, ya no la reconoce como chr, sino como Date.

Una vez hecho esto podemos graficar:

expos_yaxis<-seq(900,2200,by=200)#nueva secuencia para el eje Y

expor<-ggplot(data=expos)+
        geom_line(aes(x=fecha, y=exp_ag_total),cex=1, col="#F91C09")+
        theme(plot.caption=element_text(hjust=0,size=9),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              plot.subtitle =element_text(hjust=0.5, size=12,face="bold"),
              axis.text.x=element_text(angle =45,vjust =1, hjust=1),
              legend.position = "right")+
        labs(title="Balanza de productos agropecuarios",
             subtitle = "Exportaciones totales",
             caption="Fuente: Banco de información económica, INEGI.")+
             xlab("Años")+
             ylab("Millones de dólares")+
        ylim(900,2200)+
        #con ylim() definimos los límites del eje Y.
        #Como valor mínimo del eje Y elegí 900 y como máximo 2200
        scale_y_continuous(breaks=expos_yaxis,label=comma)

expor

Como podemos ver, para el eje X, solo muestra los años comprendidos en toda la serie, desde 2018 hasta 2021, y no en formato de fecha. Para poder ilustrarlo en formato de fecha ya no podemos usar la función scale_x_continuous(), usaremos una nueva: scale_x_date() para poder manipular el eje X como un eje de fechas.

Los argumentos de scale_x_date() que usaremos son date_labels y date_breaks. El primero es para decidir el formato en que aparecerá la fecha, en este caso elijo día-mes-año (“%d/%m/%Y”). Con date_breaks elejimos los cortes del eje X, en este caso elijo un mes, es decir, aparecerán las marcas del eje X mes con mes.

expor<-ggplot(data=expos)+
        geom_line(aes(x=fecha, y=exp_ag_total),cex=1, col="#F91C09")+
        theme(plot.caption=element_text(hjust=0,size=9),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              plot.subtitle =element_text(hjust=0.5, size=12,face="bold"),
              axis.text.x=element_text(angle =45,vjust =1, hjust=1),
              legend.position = "right")+
        labs(title="Balanza de productos agropecuarios",
             subtitle = "Exportaciones totales",
             caption="Fuente: Banco de información económica, INEGI.")+
             xlab("Años")+
             ylab("Millones de dólares")+
        scale_color_manual(" ",values=c("#FC4E07"))+
        ylim(900,2200)+
        scale_y_continuous(breaks=expos_yaxis,label=comma)+
        scale_x_date(date_labels = "%d/%m/%Y",  #poner atención
                     date_breaks = "1 month")   #poner atención

expor

Se observa que el eje X está un poco saturado, si queremos mostrar menos fechas únicamente manipulamos el argumento date_breaks cambiando “1 month” por “2 month”.

expor<-ggplot(data=expos)+
        geom_line(aes(x=fecha, y=exp_ag_total),cex=1, col="#F91C09")+
        theme(plot.caption=element_text(hjust=0,size=9),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              plot.subtitle =element_text(hjust=0.5, size=12,face="bold"),
              axis.text.x=element_text(angle =45,vjust =1, hjust=1),
              legend.position = "right")+
        labs(title="Balanza de productos agropecuarios",
             subtitle = "Exportaciones totales",
             caption="Fuente: Banco de información económica, INEGI.")+
             xlab("Años")+
             ylab("Millones de dólares")+
        scale_color_manual(" ",values=c("#FC4E07"))+
        ylim(900,2200)+
        scale_y_continuous(breaks=expos_yaxis,label=comma)+
        scale_x_date(date_labels = "%d/%m/%Y", 
                     date_breaks = "2 month")   #poner atención

expor

Gráfico de líneas con dos ejes Y

Hay veces que queremos comparar dos series en un mismo gráfico, pero estas series tienen unidades de medida diferente, lo cual las hace no comparables, por eso es necesario agregar un segundo eje Y.

Para lograr este cometido usaremos la base ginipib, la cual muestra el coeficiente de Gini y el PIB per cápita en miles de pesos con base 2013.

El coeficiente de Gini mide la desigualdad en la distribución del ingreso en una escala de 0 a 1. El pib per cápita es el PIB dividido entre el número de habitantes, aquí se presenta en miles de pesos.

head(ginipib)
##    año  GINI PIBmiles2013
## 1 2000 0.495      146.761
## 2 2001 0.480      144.278
## 3 2002 0.466      142.390
## 4 2003 0.467      142.658
## 5 2004 0.469      146.399
## 6 2005 0.470      147.870

Grafiquemos cada variable individualmente:

gini_plot<-ggplot(ginipib, aes(x=año, y=GINI))+
        geom_line(col = "#FC4E07",size=1)+
        theme(plot.caption=element_text(hjust=0,size=9),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              axis.text.x=element_text(angle =45,vjust =1, hjust=1))+
        labs(title="México: Coeficiente de Gini",
             caption="Fuente: ENIGH, INEGI.")+
             xlab("Años")+
             ylab(" ")+
        scale_x_continuous(breaks=infla_xaxis)
        

gini_plot

gini_plot<-ggplot(ginipib, aes(x=año, y=PIBmiles2013))+
        geom_line(col = "#00AFBB",size=1)+
        theme(plot.caption=element_text(hjust=0,size=9),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              axis.text.x=element_text(angle =45,vjust =1, hjust=1))+
        labs(title="México: PIB per cápita",
             caption="Fuente: Elaboración propia con información de INEGI.")+
             xlab("Años")+
             ylab("Miles de pesos")+
        scale_x_continuous(breaks=infla_xaxis)
        
gini_plot

Ahora lo que queremos es graficar ambas en el mismo gráfico de líneas.

Para eso necesitamos reescalar una serie en función de la otra. Además usaremos un nuevo argumento de la función scale_y_continuous(): sec.axis.

summary(ginipib)
##       año            GINI         PIBmiles2013  
##  Min.   :2000   Min.   :0.4230   Min.   :138.9  
##  1st Qu.:2004   1st Qu.:0.4390   1st Qu.:145.2  
##  Median :2009   Median :0.4450   Median :149.3  
##  Mean   :2009   Mean   :0.4511   Mean   :148.6  
##  3rd Qu.:2014   3rd Qu.:0.4665   3rd Qu.:151.3  
##  Max.   :2018   Max.   :0.4950   Max.   :157.4
#el valor máximo de PIBmiles2013 es 157
#el valor máximo de GINI es 0.49
#157/0.49=320
coeff <- 320 #el valor máximo del Gini es 320 veces menor al máximo del PIBpc,
             #por eso debemos reescalar el segundo eje Y (el del PIBpc)


ev_ginipib <- ggplot(ginipib, aes(x=año))+
        geom_line( aes(y=GINI,color = 'Gini'),
                   size=1)+
        #Para la línea del PIBpc 
        #Dividimos toda la columna PIBmiles2013 entre el coeff(320)
        geom_line( aes(y=PIBmiles2013/coeff,color = 'PIB per cápita'), 
                   size=1)+
        labs(x="Años")+
        scale_color_manual(" ",values=c("#FC4E07", "#00AFBB"))+
        scale_x_continuous(breaks=infla_xaxis)+
        scale_y_continuous(name = "Coeficiente de Gini",
                           #aquí usamos el objeto llamado coeff
                           sec.axis = sec_axis(~.*coeff,
                                               name="Miles de pesos de 2013"))+
        theme(plot.caption=element_text(hjust=0,size=9),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              plot.subtitle =element_text(hjust=0.5, size=12,face="bold"),
              axis.text.x=element_text(angle =45,vjust =1, hjust=1),
              legend.position = "bottom")+
        labs(title="Evolución del PIB per cápita y el coeficiente de Gini",
             subtitle = "Distribución del ingreso en México",
             caption="Fuente: Elaboración propia con información de INEGI.")

ev_ginipib

Gráficos de dispersión

“Los gráficos de dispersión son la forma más común de visualización para ilustrar correlaciones (o la falta de ellas) entre dos variables -una variable es graficada a través del eje horizontal y la otra del eje eje vertical. Las observaciones específicas son graficadas en el espacio creado”.

-Jonathan Schwabish. Better data visualizations: A guide for Scholars, Researchers, and Wonks (traducción propia)

Gráfico de dispersión simple

En esta subsección se elaborará un gráfico de dispersión sencillo. Por lo cual utilizaremos la base de datos gas.

Visualizamos la base:

head(gas)
##     ï..fecha   Qgn   Pgn    Pe   PDV  CTgn  TDeu  PRpx Qshgus   Qpx  secE  Memo
## 1 01/01/2002 18.44 10.43  9.88 12.08 13.63 10.56 18.40  10.39 17.20 16.87 17.99
## 2 01/02/2002 18.43 10.21  9.88 12.08 13.62 10.56 18.40  10.39 17.16 16.72 17.96
## 3 01/03/2002 18.46 10.34  9.90 12.08 13.65 10.56 18.39  10.39 17.17 16.76 17.97
## 4 01/04/2002 18.48 10.48  9.95 12.07 13.65 10.56 18.40  10.39 17.19 16.76 17.99
## 5 01/05/2002 18.49 10.54 10.02 12.08 13.71 10.56 18.40  10.39 17.16 16.80 17.98
## 6 01/06/2002 18.50 10.52 10.02 12.08 13.75 10.56 18.40  10.39 17.12 16.91 18.00
##    ITCr  IGAE
## 1 14.24 14.41
## 2 14.23 14.38
## 3 14.19 14.41
## 4 14.20 14.43
## 5 14.25 14.45
## 6 14.29 14.43

Las variables que ocuparemos son las siguientes:

Qgn :cantidad de gas natural consumida por el mercado

Pgn :precios de venta de primera mano de gas natural

Pe :precio medio de la electricidad

IGAE:índice general de actividad económica

Para este ejercicio queremos saber cómo es afectada la variable Qgn por las demás variables, por lo que Qgn se ubicará en el eje vertical de cada gráfico.

La función a utilizar aquí es geom_point(). El resto son funciones que ya hemos utilizado.

Pgn_vs_Qgn<-ggplot(gas, aes(x=Pgn, y=Qgn))+
        geom_point(fill="#00AFBB", col="#00AFBB", size=3, shape=21)+
        labs(x="Precios de venta de primera mano de gas natural",
             y="Cantidad de gas natural")+
        theme(plot.caption=element_text(hjust=0,size=9),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              axis.text.x=element_text(angle =0,vjust =0.5, hjust=0.5))+
        labs(title="Precios contra cantidad",
             caption="Fuente: Ejercicio de clase.")
Pgn_vs_Qgn

Pe_vs_Qgn<-ggplot(gas, aes(x=Pe, y=Qgn))+
        geom_point(fill="#E7B800", col="#E7B800", size=3, shape=21)+
        labs(x="Precio medio de la electricidad",
             y="Cantidad de gas natural")+
        theme(plot.caption=element_text(hjust=0,size=9),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              axis.text.x=element_text(angle =0,vjust =0.5, hjust=0.5))+
        labs(title="Precios medios contra cantidad",
             caption="Fuente: Ejercicio de clase.")

Pe_vs_Qgn

IGAE_vs_Qgn<-ggplot(gas, aes(x=IGAE, y=Qgn))+
        geom_point(fill="#FC4E07", col="#FC4E07", size=3, shape=21)+
        labs(x="Índice general de actividad económica",
             y="Cantidad de gas natural")+
        theme(plot.caption=element_text(hjust=0,size=9),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              axis.text.x=element_text(angle =0,vjust =0.5, hjust=0.5))+
        labs(title="Actividad económica contra cantidad",
             caption="Fuente: Ejercicio de clase.")
        
IGAE_vs_Qgn

Con estos tres gráficos podemos apreciar la relación que la cantidad de gas natural consumida por el mercado tiene con el resto de las variables que nos interesan.

Gráfico de dispersión con línea de regresión ajustada

Este gráfico es casi idéntico al anterior, con la diferencia que hemos agregado la línea de regresión ajustada, esto a través del comando geom_smooth().

Las instrucciones de la función anterior son las siguientes:

method = lm: lm por linear model

se = FALSE/TRUE : se por standard error

A continuación muestro el mismo gráfico, con la diferencia de FALSE y TRUE en se.

se = FALSE

IGAE_vs_Qgn<-ggplot(gas, aes(x=IGAE, y=Qgn))+
        geom_point(fill="#FC4E07", col="#FC4E07", size=3, shape=21)+
        labs(x="Índice general de actividad económica",
             y="Cantidad de gas natural")+
        theme(plot.caption=element_text(hjust=0,size=9),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              axis.text.x=element_text(angle =0,vjust =0.5, hjust=0.5))+
        labs(title="Actividad económica contra cantidad",
             caption="Fuente: Ejercicio de clase.")+
        geom_smooth(method = lm, se= FALSE, color="#00AFBB", linetype = 'solid', cex = 1)

        
IGAE_vs_Qgn

se = TRUE

IGAE_vs_Qgn<-ggplot(gas, aes(x=IGAE, y=Qgn))+
        geom_point(fill="#FC4E07", col="#FC4E07", size=3, shape=21)+
        labs(x="Índice general de actividad económica",
             y="Cantidad de gas natural")+
        theme(plot.caption=element_text(hjust=0,size=9),
              plot.title=element_text(hjust=0.5, size=14,face="bold"),
              axis.text.x=element_text(angle =0,vjust =0.5, hjust=0.5))+
        labs(title="Actividad económica contra cantidad",
             caption="Fuente: Ejercicio de clase.")+
        geom_smooth(method = lm, se= TRUE, color="#00AFBB", linetype = 'solid', cex = 1)

        
IGAE_vs_Qgn

QQnorm: Normalidad de los residuales

En en las siguientes subsecciones usaremos gráficos comunes en el análisis de regresión lineal.

Para la presente subsección construimos un modelo de regresión lineal múltiple. Este modelo será el de la ecuación de la demanda de Gas Natural:

\(Qgn=f(Pgn, Pe, IGAE)\)

modelo_gas<-lm(data=gas, Qgn~Pgn+Pe+IGAE)
summary(modelo_gas)
## 
## Call:
## lm(formula = Qgn ~ Pgn + Pe + IGAE, data = gas)
## 
## Residuals:
##       Min        1Q    Median        3Q       Max 
## -0.166986 -0.040286 -0.002527  0.040026  0.160225 
## 
## Coefficients:
##             Estimate Std. Error t value             Pr(>|t|)    
## (Intercept) -6.06978    1.27083  -4.776           0.00000481 ***
## Pgn         -0.03100    0.01709  -1.814               0.0720 .  
## Pe           0.15080    0.05826   2.588               0.0108 *  
## IGAE         1.62565    0.10861  14.968 < 0.0000000000000002 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.06578 on 128 degrees of freedom
## Multiple R-squared:  0.8545, Adjusted R-squared:  0.8511 
## F-statistic: 250.7 on 3 and 128 DF,  p-value: < 0.00000000000000022

(En este momento no es de nuestro interés saber interpretar el modelo o si este es válido).

Una vez construido el modelo pasamos a la graficación de sus residuales.

Para esto ya no usaremos la base de datos gas, en su lugar usaremos el modelo que acabamos de construir: modelo_gas.

Para los valores que irán en los ejes poner especial atención en aes().

Con geom_abline() agregamos la línea recta que cruzará por los puntos, esto con el fin de visualizar de una forma más cómoda si los residuales del modelo son normales.

probplot<-ggplot(data= modelo_gas, aes(qqnorm(.stdresid)[[1]], .stdresid))  + #ojo aquí 
        geom_point(fill="#00AFBB",col="#00AFBB",shape=21, size=3)+
        theme(plot.title=element_text(hjust=0.5, size=14,face="bold"),
              axis.text.x=element_text(angle =0,vjust =0.5, hjust=0.5))+
        labs(title="QQnorm: Normalidad de los residuales")+
        xlab("Cuantiles teóricos")+
        ylab("Cuantiles de muestra")+
        geom_abline(col="#0012BB", cex=1)
probplot

Heterocedasticidad: Residuales contra valores ajustados

Para comprobar el supuesto de homocedasticidad comparamos los residuales del modelo contra los valores ajustados.

Las funciones a utilizar son:

geom_jitter(): que es muy parecida a geom_point().

geom_hline(): para trazar el eje Y en 0 (yintercept = 0).

Nuevamente ponemos atención en los valores dentro de aes().

resid_vs_ajust<-ggplot(data = modelo_gas, aes(x = .fitted, y = .resid)) +
        geom_jitter(fill="#4D05AC", col="#4D05AC", size=3, shape=21) +
        theme(plot.title=element_text(hjust=0.5, size=14,face="bold"),
              axis.text.x=element_text(angle =0,vjust =0.5, hjust=0.5))+
        geom_hline(yintercept = 0, size=1) +
        xlab("Valores ajustados") +
        labs(title="Residuales contra Valores ajustados")+
        ylab("Residuales")

resid_vs_ajust

Variables independientes contra residuales

resid_vs_Pgn<-ggplot(data = gas, aes(x = Pgn, y = modelo_gas$residuals)) + #y = modelo_gas$residuals
        geom_jitter(fill="#084714", col="#084714", size=3, shape=21) +
        theme(plot.title=element_text(hjust=0.5, size=14,face="bold"),
              axis.text.x=element_text(angle =0,vjust =0.5, hjust=0.5))+
        geom_hline(yintercept = 0, size=1) +
        xlab("Pgn: precios de venta del gas natural") +
        labs(title="Pgn contra residuales")+
        ylab("Residuales")

resid_vs_Pgn

Gráfico de dispersión con etiquetas de datos

Para esta sección crearemos un dataframe rapidamente:

año<-c("2000","2002","2004","2006",
       "2008","2010","2012","2014",
       "2016","2018")

GINI<-round(c(0.494953,0.465956,0.468544,0.422745,0.458614,
              0.435979,0.441441,0.439463,0.449856,0.427178), 3)

PIBpc_miles<-c(146.76,142.39,146.40,151.08,149.68,
               142.94,149.39,151.20,155.35,157.41)

pobreza<-c(53.61,49.98,47.21,42.87,44.36,46.11,
           45.48,46.17,43.56,41.91)

dist_ing<-data.frame(año,GINI,pobreza,PIBpc_miles)

head(dist_ing)
##    año  GINI pobreza PIBpc_miles
## 1 2000 0.495   53.61      146.76
## 2 2002 0.466   49.98      142.39
## 3 2004 0.469   47.21      146.40
## 4 2006 0.423   42.87      151.08
## 5 2008 0.459   44.36      149.68
## 6 2010 0.436   46.11      142.94

Ahora pasamos a los gráficos:

Las etiquetas de datos serán los años correspondientes a las observaciones.

pib_vs_pobreza<-ggplot(dist_ing, aes(x=PIBpc_miles, y=pobreza))+
        geom_point(fill="#00AFBB", col="black", size=3, shape=21)+
        theme_grey()+
        theme(plot.title=element_text(hjust=0.5,size=12,face="bold"))+
        labs(title="PIB per cápita contra pobreza",
             x="PIB per cápita en miles de pesos de 2013",
             y="% de la población total")+
        geom_smooth(method = lm, se= FALSE, color="#00AFBB", linetype = 'dashed', cex = 1)+
        geom_label_repel(label=año, size = 4,hjust = 0.5)

pib_vs_pobreza

pib_vs_gini<-ggplot(dist_ing, aes(x=PIBpc_miles, y=GINI))+
        geom_point(fill="#E7B800", col="black", size=3, shape=21)+
        theme(plot.title=element_text(hjust=0.5,size=12,face="bold"))+
        labs(title="PIB per cápita contra Gini",
             x="PIB per cápita en miles de pesos de 2013",
             y="GINI de ingresos totales corrientes")+
        geom_smooth(method = lm, se= FALSE, color="#E7B800", linetype = 'dashed', cex = 1)+
        geom_label_repel(label=año, size = 4,hjust = 0.5)

pib_vs_gini

pobreza_vs_gini<-ggplot(dist_ing, aes(x=pobreza, y=GINI))+
        geom_point(fill="#FC4E07", col="black", size=3, shape=21)+
        theme(plot.title=element_text(hjust=0.5,size=12,face="bold"))+
        labs(title="Pobreza contra Gini",
             x="% de la población total",
             y="GINI de ingresos totales corrientes")+
        geom_smooth(method = lm, se= FALSE, color="#FC4E07", linetype = 'dashed', cex = 1)+
        geom_label_repel(label=año, size = 4,hjust = 0.5)

pobreza_vs_gini

grid.arrange()

Con esta función unimos los gráficos anteriores en uno solo:

grid.arrange(pib_vs_gini, pib_vs_pobreza, ncol=2)