Fecha de la ultima revisión
## [1] "2023-08-22"
library(ggplot2)
library(ggversa)
library(lubridate)
library(tidyverse)
En este modulo se muestra una de las grandes ventajas de usar ggplot2. Para la producción de un gráfico por diferentes grupos o categorías, se usa la opción de facet_wrap(); o sea, cada grupo genera la producción de un gráfico. Por ejemplo, observe en la Figura que cada localidad de muestreo genera su propio gráfico. Para lograr esos cuatro gráficos, se necesitaron tres variables, en que por lo menos una es categórica. En este ejemplo se representa la cantidad de Anolis muestreado en el periodo seco y lluvioso separado por las cuatro localidades en el bosque usando geom_bar. Note la tilde, ~, antes del nombre de la variable categórica Survey_Site.
barraA=ggplot(Anolis, aes(SEX_AGE, fill=SEASON))
barraA+geom_bar()+
facet_wrap(~Survey_Site)+
labs(y="Frecuencia", x="Género y edad")+
theme(axis.title=element_text(size=10,face="bold"))
En el próximo gráfico se usa geom_point combinado con facet_wrap con las variables de tamaño de los Anolis y la altitud del lugar de muestreo en donde el lagarto fue encontrado.
barraC=ggplot(Anolis, aes(SVL, HEIGHT))
barraC+geom_point()+
facet_wrap(~Survey_Site)+
labs(y="Altura del muestreo")+
theme(axis.title=element_text(size=10,face="bold"))
Para cambiar la cantidad de columnas o filas se usa nrow y ncol. En el ejemplo ponemos todos los gráficos en una fila con nrow igual a 1.
barraD=ggplot(Anolis, aes(SVL, HEIGHT))
barraD+geom_point()+
facet_wrap(~Survey_Site, nrow=1)+
labs(y="Altitud")+
theme(axis.title=element_text(size=10,face="bold"))
Por otro lado, en el próximo ejemplo reorganizamos los gráficos para que queden uno debajo de los otros en una columna con ncol igual a 1.
barraC=ggplot(Anolis, aes(SVL, HEIGHT))
barraC+geom_point()+
facet_wrap(~Survey_Site, ncol=1)+
labs(y="Altitud")+
theme(axis.title=element_text(size=10,face="bold"))
***
A veces queremos tener los gráficos por categoría sobre la misma columna ncol=1 pero que a la misma vez la escala de cada grupo se refleje de acuerdo a los datos. Note que en el gráfico anterior todas los gráficos tienen la misma escala de 0 a 60. Si queremos que las escalas en los ejes de X y Y queden ajustadas de acuerdo a los datos de cada grupo, se utiliza la opción y parámetro (scales=“free”) . Note en la Figura que ahora cada gráfico tiene su propria escala:
barraC=ggplot(Anolis, aes(SVL, HEIGHT))
barraC+geom_point()+
facet_wrap(~Survey_Site, ncol=1, scales="free")+
labs(y="Altitud")+
theme(axis.title=element_text(size=10,face="bold"))
***
Podríamos también querer organizar los gráficos de acuerdo a múltiples variables categóricas mostrando así la agrupación de los datos. En el ejemplo se agrupan de acuerdo al sitio de muestreo (Gap, North, South o Woods) y al periodo del año (seco o mojado). De esta forma, se pueden producir gráficos agrupados por múltiples variables discretas. Note que lo único que se tuvo que hacer fue añadir ~variable1 + variable2; en nuestro caso, ~Survey_Site + SEASON.
barraE=ggplot(Anolis, aes(SVL, HEIGHT))
barraE+geom_point()+
facet_wrap(~Survey_Site+SEASON)+
labs(y="Altitud")+
theme(axis.title=element_text(size=10,face="bold"))
***
En el ejemplo que hemos estado mostrando hay localidades en que no hay datos, como en Gap Tower en la época lluviosa, en South Tower en la época seca, y en Woods Walkway Tower en la época lluviosa, y por eso no aparecen en la figura. Si queremos mostrar los gráficos de esos sitios donde no existe información, se usa la opción de drop = FALSE.
barraE=ggplot(Anolis, aes(SVL, HEIGHT))
barraE+geom_point()+
facet_wrap(~Survey_Site+SEASON,drop=FALSE)+
labs(y="Altitud")+
theme(axis.title=element_text(size=10,face="bold"))
***
En la Figura anterior todos los graficos muestran la misma escala para cada uno. Para que cada uno tenga su propia escala, nuevamente usamos scales=free.
barraF=ggplot(Anolis, aes(SVL, HEIGHT))
barraF+geom_point()+
facet_wrap(~Survey_Site, scales="free")+
labs(y="Altitud")+
theme(axis.title=element_text(size=10,face="bold"))
A veces puede ser más fácil interpretar los datos y la distribución de un grupo si estos están solapados con los datos de los otros grupos, especialmente si se usan colores diferentes por grupo. Una alternativa es graficar todos los datos en cada uno de los gráficos individuales, pero que los que no son del gráfico que no se quiere resaltar se muestren en un color más atenuado, mientras que los datos que se quieren resaltar salgan en un color más prominente. Para lograr ese efecto, a continuación se crea un nuevo data frame con data = transform(Anolis, Survey_Site = NULL) basándonos en el data frame anterior. Con la opción NULL estamos removiendo la variable que usamos para hacer el facetting; o sea, la distribución de datos por categoría, que en nuestro caso es Survey_Site. También se le añade un color diferente a los cuatro grupos. Note que el código para el color atenuado, en este caso grey85, tiene que escribirse antes del código que graficará la variable que queremos resaltar con color Survey_Site, ya que esta última estará en una capa superior y, a consecuencia, se esconderán algunos de los puntos de la capa inferior.
ggplot(Anolis, aes(x=SVL, y=HEIGHT, colour=Survey_Site))+
geom_point(data = transform(Anolis,
Survey_Site = NULL), colour = "grey85")+
geom_point()+
facet_wrap(~Survey_Site)+
labs(y="Altitud")+
theme(legend.position="none")
Para que el nombre de cada grupo salga debajo de cada gráfico en el eje de X, usar strip.position = “bottom”, “top”, “left”, “right”:
ggplot(Anolis, aes(x=SVL, y=HEIGHT, colour=Survey_Site))+
geom_point(data = transform(Anolis,
Survey_Site = NULL), colour = "grey85")+
geom_point()+
facet_wrap(~Survey_Site, strip.position = "bottom")+
labs(y="Altitud")+
theme(legend.position="none")
El nombre de cada grupo se cambia al eje de Y al usando la función switch=y.
ggplot(Anolis, aes(x=SVL, y=HEIGHT, colour=Survey_Site))+
geom_point(data = transform(Anolis,
Survey_Site = NULL), colour = "grey85")+
geom_point()+
facet_wrap(~Survey_Site, strip.position = "left")+
labs(y="Altitud")+
theme(legend.position="none")
## Warning: Removed 1232 rows containing missing values (`geom_point()`).
## Warning: Removed 308 rows containing missing values (`geom_point()`).
Facet_wrap se puede usar en combinación con todas las funciones tipo geom. A continuación se demostrará un ejemplo con geom_line. Para visualizar las ventajas de esa combinación, utilizaremos datos sobre las temperaturas mínimas diurnas de la ciudad de Morelia, Michoacán, México, disponible en CLIMCOM, http://clicom-mex.cicese.mx. Los datos del archivo original van de noviembre 1947 a marzo del 2012. A continuación solo se mostrarán del 1951 hasta el 1959. Note que aparecen todos los años juntos, lo que lo hace un poco difícil de analizar. Para reproducir este gráfico, primero hay que instalar y activar la librería lubridate que se usará para manipular los datos relacionados a las fechas. En el paquete lubridate se encuentra una serie de funciones para reorganizar y manipular datos de fechas y horas en distintos formatos. El segundo paso es seleccionar solamente los datos de interés con la opción with. El tercer paso es convertir los datos de fecha que estén en tres columnas, Mes, Dia y Year (o Año), y crear una columna de fecha donde la organización de la fecha es año-mes-día. El paso final es convertir la fecha al día del año (1-365).
Veamos las primeras filas del archivo, donde en la primera se muestra que en el 8 de octubre de 1947 la temperatura mínima fue de 11C°.
head(MORELIA.MICH.Tmin)
## Mes Dia Year Tmin
## 1 10 8 1947 11.0
## 2 10 9 1947 11.0
## 3 10 10 1947 9.0
## 4 10 11 1947 10.0
## 5 10 12 1947 12.0
## 6 10 13 1947 12.5
Ahora se selecciona solamente parte de los datos, del 1 de enero del 1951 al 31 de diciembre del 1959.
MM=MORELIA.MICH.Tmin%>%
filter(Year>1950 & Year<1960)
Ahora se define la variable para la fecha con la función ymd para indicar que el orden de la fecha es año-mes-día. También se identifica cuántos dígitos tiene cada elemento de la fecha utilizando %04 para 4 cifras para el año y %02 para dos cifras para mes y día. Subsiguientemente se identifica a cuál columna corresponde ubicar a cada uno.
library(lubridate)
MM$fecha <- with(MM, ymd(sprintf('%04d%02d%02d',
Year, Mes, Dia)))
head(MM)
## Mes Dia Year Tmin fecha
## 1 1 1 1951 4.0 1951-01-01
## 2 1 2 1951 10.0 1951-01-02
## 3 1 3 1951 1.0 1951-01-03
## 4 1 4 1951 1.0 1951-01-04
## 5 1 5 1951 1.5 1951-01-05
## 6 1 6 1951 3.0 1951-01-06
Con la función yday se puede identificar cuál día de los 365 del año es que corresponde dentro de cada una de las fechas. Por ejemplo, el primero de enero corresponde al día 1 y el día 15 de febrero corresponde al día 46 del año (31 días de enero más los 15 días de febrero), y así sucesivamente. La nueva variable diaanual recoge esa información:
library(lubridate)
MM$diaanual=yday(MM$fecha)
tail(MM)
## Mes Dia Year Tmin fecha diaanual
## 3282 12 26 1959 1.1 1959-12-26 360
## 3283 12 27 1959 1.7 1959-12-27 361
## 3284 12 28 1959 1.1 1959-12-28 362
## 3285 12 29 1959 0.0 1959-12-29 363
## 3286 12 30 1959 -0.6 1959-12-30 364
## 3287 12 31 1959 -1.1 1959-12-31 365
Veamos ahora el resultado. El gráfico de la figura produce una línea por cada año. Note que hay que identificar que el año es un factor usando color=factor(Year). Si no se hace así, el año se interpretará como un valor continuo.
ggplot(MM, aes(x=diaanual, y=Tmin, color=factor(Year)))+
geom_line()+
theme(axis.title=element_text(size=10,face="bold"))+
xlab("Día del año")+
ylab("Temperatura mínima")
Como podemos apreciar en la Figura las líneas que representan las fechas son muy difíciles de analizar debido al solapamiento. Ahora utilizamos facet_wrap para que aparezcan separadas por la categoría de año, Year. Note la tilde en facet_wrap, ~, antes del nombre de la variable categórica, Year.
ggplot(MM, aes(x=diaanual, y=Tmin, color=factor(Year)))+
geom_line()+
facet_wrap(~Year)+
theme(legend.position="none")+
theme(axis.title=element_text(size=10,face="bold"))+
xlab("Día del año")+
ylab("Temperatura mínima")
Por omisión, los gráficos van a la horizontal primero (de izquierda a derecha) y luego hacia abajo. Si se desea que bajen a la vertical primero (de arriba para abajo) y luego a la izquierda, se usa la opción dir. De esa manera, se puede notar que ahora se llena la primera columna, después la segunda y luego la tercera columna, y así sucesivamente. Para lograr ese efecto se utilizó la opción dir=v en la función facet_wrap, v de vertical; o sea, que baje a la vertical primero.
ggplot(MM, aes(x=diaanual, y=Tmin, color=factor(Year)))+
geom_line()+
facet_wrap(~Year, dir="v")+
theme(legend.position="none")+
labs(y="Temperatura mínima", x="Día del año")+
theme(axis.title=element_text(size=10,face="bold"))
ggplot(el archivo de datos, aes(la variable continua))
facet_wrap(\(\sim\) a + b, scales, nrow, ncol, switch, drop, dir)
facet: \(\sim\) a + b o se puede usar un vector c(a + b)
scales: usar free si se quiere que las escalas sean determinadas por los gráficos individualmente o que todos los gráficos tengan la misma escala
nrow: la cantidad de filas
ncol: la cantidad de columnas
switch: presenta la identificación de la categoría abajo cuando se usa X, y a la izquierda cuando se usa Y
drop: añadir drop = FALSE para que muestre también las variables que no tienen información
dir: dirección h para horizontal y v vertical h es la dirección predeterminada