Este cuaderno es una guía para facilitar el desarrollo de la actividades en clase de los cursos: Hidroclimatológia (pregrado y posgrado) y Modelación de procesos hidrológicos de la FEAR-PUJ, y fue consolidado con la ayuda de Oscar Cadena y Sergio Narvaez (estudiantes de la Maestría en Hidrosistemas de la PUJ).

Así mismo, este cuaderno describe como se pueden generar gráficos de series de tiempo con doble eje, un eje normal en orden ascendente y el otro eje en orden inverso utilizando el plot básico de R y el paquete ggplot2. Para estos ejemplos utilizaremos una serie de tiempo de “caudales en [m3/s]” y “precipitación en [m]”, con escala temporal diaria y con vacíos de información “NA”, en el periodo de tiempo de 1/enero/1996 hasta 31/diciembre/2020.

Método 1: Función Base de R - Plot

El programa Rstudio cuenta con herramientas para realizar la generación de gráficos de doble eje, usando la librería “lubridate” para el reconocimiento de datos con formato de fecha (dd/mm/yyyy).

Antes de iniciar, es recomendable iniciar limpiando el espacio de trabajo y llamando de una vez todos las librerías que se vayan a necesitar. Si no se tiene instalada alguna de las librerías es necesario hacerlo con el comando install.packages. Así mismo, se selecciona el directorio de trabajo donde se tiene el archivo con la información a procesar.

library("lubridate") # para el uso de series de tiempo
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union

Una vez instalados los paquetes requeridos, por favor indique con el comando setwd la ubicación de la CARPETA donde tiene los archivos con los que vamos a trabajar.Por favor recuerde que para correr este comando debe usar DOBLE SLASH. Es recomendable que cree una carpeta de trabajo para este curso y que esta no este guardada en la nube (OneDrive) para evitar problemas de sincronización por falta de internet durante las clases.

rm(list = ls()) #limpia el área de trabajo

# Carpeta de trabajo
setwd("D://Javeriana//Scripts - R") 

Se carga el archivo “.csv” con su nombre específico, ya dentro del directorio de trabajo, mediante la función “read.csv”. Con el comando header=T, lo que indica que se leerá la primera fila como los nombres de cada columna, en el caso de usar “FALSE, la primera línea sera leída y tomada como dato. Luego previsualizamos los datos de cabecera y su formato original.

Datos <- read.csv("doble_eje.csv", # Lectura del archivo ".csv" con su nombre específico
                  header = T, sep = ";") # Lectura de la primera linea como nombres de las columnas
head(Datos)# Para mostrar los datos de cabecera
##       Fecha           P     Q
## 1 1/01/1996 0.000053463 17.08
## 2 2/01/1996 0.000871265 13.48
## 3 3/01/1996 0.001268084 12.80
## 4 4/01/1996 0.000145976 12.35
## 5 5/01/1996 0.000010700 13.92
## 6 6/01/1996 0.001237270 13.25

En este ejercicio, no ajustaremos el formato de fecha si no que crearemos una secuencia de datos de fechsa usando la función as.Date. Si requiere ajustar la serie de datos de la tabla, por favor use la función xts aplicada en lso ejercicios de caracterización.

Datos[,1] <- seq(from=as.Date("01-01-1996",format="%d-%m-%Y"),
            to=as.Date("31-12-2020",format="%d-%m-%Y"),by="day") #creamos una secuencia para la serie de tiempo

Mediante el comando “par(mar())”, ajustmos los parámetros de trazado, donde utiliza un vector numérico de longitud=4, que establece los tamaños de los márgenes en el siguiente orden: inferior, izquierdo, superior y derecho.

# Dibuja la primera gráfica usando el eje y1
par(mar = c(3, # Margen inferior
            4, # Margen izquierdo
            3, # Margen superior
            4) + 0.3) # Margen derecho  

Realizamos la impresión de la primera gráfica “Fecha vs Q”, es decir la serie de tiempo de caudal, donde es posible modificar el tipo de linea con la función type=(p=puntos, l=líneas, b=Ambos (puntos y líneas, separados), s=escaleras, h= histograma, n=vacío), luego con la función ylim se asignan los límites mínimos y máximos del eje vertical, la función col define el color, ej. col = “blue” (definir lso colores siempre en inglés) o mediante el uso de colores RGB. Si desea mayor detalle sobre los colores ingrese aquí. Finalmente, con la función ylab se nombra el eje vertical (y) y con xlab el eje horizontal (x).

plot(Datos$Fecha, Datos$Q, # Datos de los ejes
     type="l", # Tipo de trazo
     ylim = c(min(na.omit(Datos$Q)), # Valor minimo eje y (ignora los datos NA)
              max(na.omit(Datos$Q))), # Valor maximo eje y (ignora los datos NA)
     col = 4, # Color del grafico
     ylab="Caudal [m3/s]", # Nombre del Eje y1
     xlab="Años")  # Nombre del Eje x

El comando par(new=True) puede ser usado si desea superponer un nuevo eje vertical sobre el anterior gráfico.

Se dibuja la segunda gráfica usando el eje derecho para los valores de Precipitación, es decir (Fecha vs P), de manera similar al grafico anterior, pero eligiendo otro color para diferenciarlo de las líneas de caudal y mediante la función “axes =FALSO” se elimina el eje vertical nuevo para evitar la superposición.

Finalmente, se agrega el nuevo eje vertical mediante la función “axis”, que ahora estara ubicado en la parte derecha, mediante el uso de la función side=4 cuyo rango de trabajo esta definido por la convención: 1=abajo, 2=izquierda, 3=arriba y, 4=derecha. Luego leemos y colocamos los valores del nuevo eje. Se puede observar que el comando ylim=rev() esto indica que el nuevo eje estara con valores invertidos. Con la función mtext se nombra el nuevo eje vertical, en posicion derecha “side=4” y con “line =3” ubicamos la posicion horizontal del nombre eje y2.

# Dibuja la primera gráfica usando el eje Q
par(mar = c(3, # Margen inferior
            4, # Margen izquierdo
            3, # Margen superior
            4) + 0.3) # Margen derecho             
plot(Datos$Fecha,Datos$Q, # Datos de los ejes
     type="l", # Tipo de trazo
     ylim = c(min(na.omit(Datos$Q)), # Valor minimo eje y1 (ignora los datos NA)
              max(na.omit(Datos$Q))), # Valor maximo eje y1 (ignora los datos NA)
     col = 4, # Color del grafico
     ylab="Caudal [m3/s]", # Nombre del Eje y1
     xlab="Años")  # Nombre del Eje x

# Se establece el parámetro new=True para un nuevo eje
par(new = TRUE)         

# Dibuja la segunda gráfica usando el eje y2
plot(Datos$Fecha,Datos$P, # Datos de los ejes
     type="l", # Tipo de trazo
     col = 5, # Color del grafico
     axes = FALSE, # Elimina el eje
     ylim = rev(c(min(na.omit(Datos$P)), # Valor minimo eje y1 (ignora los datos NA) "rev()":INVIERTE EL EJE nuevo y2
                  max(na.omit(Datos$P)))), # Valor maximo eje y1 (ignora los datos NA)
     xlab="", # Nombre del Eje x
     ylab="") # Nombre del Eje y2

axis(side = 4, at = pretty(range(Datos$P)))      
mtext("Precipitacion [m]", # Añade texto al nuevo eje
      side = 4, # Posición del texto (1=abajo, 2=izquierda, 3=arriba, 4=derecha)
      line = 3) # Posición horizontal del nombre eje y2

El gráfico resultante nos muestra la serie de tiempo a nivel diario, mostrando el caudal en el eje vertical izquierdo y la precipitación en el eje vertical derecho con valores inversos para una mejor visualiazción, y en el eje horizontal compartido por ambas gráficas la variable de tiempo.

Método 2 - Paquete GGPLOT2

De la misma manera que el ejemplo anterior utilizamos los mismos datos de entrada, y las librerías ggplot2 y lubridate para realizar el procedimiento.

Como seguimos trabajando en el mismo directorio y con el mismo archivo no es necesario repetir el proceso inicial y podemos ir directamente al uso de la función ggplot para graficar. Mediante el comando “ggplot”, ingrersamos los datos del data.frame nombrado anteriormente “Datos”, luego “aes” asigna los datos de cada eje para un primer gráfico ejemplo “caudal vs tiempo”, “geom_line” indica el grosor de linea con “size” y su color como el ejemplo “color=”blue”” , por ultimo con “labs(title=”“) colocamos el nombre de la gráfica.

ggplot(data = Datos, 
       aes(x = Fecha, y = Q)) + 
  geom_line(size=1, 
            color = "blue") + 
  labs(title = "Caudal (m3/s)")
## Warning: Removed 922 row(s) containing missing values (geom_path).

Ahora agregamos al gráfico de caudal un segundo gráfico en nuestro caso de ejemplo la precipitación, de la misma manera escogiendo el grosor de linea y el color. Con “Labs” renombramos el grafico nuevo y nombramos el nuevo eje vertical. En esta seccion utilizamos “na.omit()” para omitir los datos faltantes y modificamos los valores de percipitación para que esten invertidos respecto al eje izquierdo, restando del valor máximo del eje izquierdo, y los niveles del eje de la misma manera.

#agregamos al gráfico de caudal un segundo eje con los valores de precipitación

ggplot(data = Datos, aes(x = Fecha, y = Q)) + 
  geom_line(size = 1, color = "blue") + 
  geom_line(aes(y = max(na.omit(Q))-(P*1000)), size = 1, color = "green")+ #Invertimos los valores de la segunda variable, restandolas del valor maximo de la primera variable
  scale_y_continuous(sec.axis = sec_axis(~.-max(na.omit(Datos$Q)), name = "P (m)")) # Invertimos los niveles del eje nuevo restandolos del valor maximo del eje izquierdo
## Warning: Removed 922 row(s) containing missing values (geom_path).

Método 3 - Paquete latticeExtra

De la misma manera que el ejemplo anterior utilizamos los mismos datos de entrada, con esto en mente utilizamo las librerias “lubridate” y “latticeExtra”

library("lubridate")# para el uso de series de tiempo
library("latticeExtra")# Hace que funcione xyplot
## Loading required package: lattice
## 
## Attaching package: 'latticeExtra'
## The following object is masked from 'package:ggplot2':
## 
##     layer

Mediante el uso de la función xyplot se agregan dos ejes y se construye cada serie por separado, asignando cada gráfico a un valor de variable indeendiente, teneindo en cuenta que la segunda gráfica tendrá el eje vertical de forma inversa mediante el uso de la función rev(), como se muestra a continuación:

# se agrega dos ejes Y se construye cada serie por separado
obj1 <- xyplot(Q ~ Fecha, Datos, # datos de entrada
               type = "l", # Tipo de trazo
               ylim = c(min(na.omit(Datos$Q)), # Dato mínimo del eje y
               max(na.omit(Datos$Q))), # Dato máximo del eje y
               lwd=2, # Grosor de la linea
               ylab="Caudal [m3/s]", # Nombramos el eje y
               xlab="Fecha") # Nombramos el eje x

obj2 <- xyplot(P ~ Fecha, Datos, 
               type = "l",
               ylim = rev(c(min(na.omit(Datos$P)),
               max(na.omit(Datos$P)))), 
               lwd=2,
               ylab="Precipitación [m]")

Finalmente con el comando “doubleYScale” sobreponemos ambas gráficas.

#Se realiza la grafica con el segundo eje Y
doubleYScale(obj1, obj2, add.ylab2 = TRUE)

Como podemos observar de la misma manera que los demas ejemplos obtenemos la gráfica con dos ejes verticales, el segundo con valores invertidos.