ggplot2: Adición de un eje x transformado secundario en la parte superior de la ttwig

[ Edición de abril de 2016: la solución en este hilo ya no muestra correctamente el eje agregado; se ha abierto un nuevo hilo sobre este tema en ggplot2 ¿2.1.0 rompió mi código? El eje secundario transformado ahora aparece incorrectamente ]

Estoy trabajando con datos X a escala y necesito agregar un eje x sin escala a la parte superior del gráfico para facilitar la interpretación. Me encontré con un enfoque para agregar un eje y secundario a ¿Cómo puedo poner una escala transformada en el lado derecho de un ggplot2? . Sin embargo, no puedo hacer que funcione correctamente para el eje x. Estoy seguro de que no entiendo una parte del código, pero parece que no puedo descifrar qué es. Intenté buscar en los archivos de ayuda de ggplot2, y también en el libro de groggot2 de Wickham: Gráficos elegantes para análisis de datos, pero si alguien puede indicarme alguna documentación relevante, ¡realmente lo agradecería!

Estoy trabajando con los datos de temperatura, pero usaré los datos del lago del enlace de arriba ya que el código fue escrito para eso. Aquí está el código de orignal de ese enlace:

library(ggplot2) library(gtable) library(grid) LakeLevels<-data.frame(Day=c(1:365),Elevation=sin(seq(0,2*pi,2*pi/364))*10+100) p1 <- ggplot(data=LakeLevels) + geom_line(aes(x=Day,y=Elevation)) + scale_y_continuous(name="Elevation (m)",limits=c(75,125)) p2<-ggplot(data=LakeLevels)+geom_line(aes(x=Day, y=Elevation))+ scale_y_continuous(name="Elevation (ft)", limits=c(75,125), breaks=c(80,90,100,110,120), labels=c("262", "295", "328", "361", "394")) #extract gtable g1<-ggplot_gtable(ggplot_build(p1)) g2<-ggplot_gtable(ggplot_build(p2)) #overlap the panel of the 2nd plot on that of the 1st plot pp<-c(subset(g1$layout, name=="panel", se=t:r)) g<-gtable_add_grob(g1, g2$grobs[[which(g2$layout$name=="panel")]], pp$t, pp$l, pp$b, pp$l) ia <- which(g2$layout$name == "axis-l") ga <- g2$grobs[[ia]] ax <- ga$children[[2]] ax$widths <- rev(ax$widths) ax$grobs <- rev(ax$grobs) ax$grobs[[1]]$x <- ax$grobs[[1]]$x - unit(1, "npc") + unit(0.15, "cm") g <- gtable_add_cols(g, g2$widths[g2$layout[ia, ]$l], length(g$widths) - 1) g <- gtable_add_grob(g, ax, pp$t, length(g$widths) - 1, pp$b) # draw it grid.draw(g) 

Para probar un método para agregar un eje x en lugar del eje y, cambié los ejes xey, y cambié el axis-l al axis-b para dar:

 library(ggplot2) library(gtable) library(grid) LakeLevels<-data.frame(Day=c(1:365),Elevation=sin(seq(0,2*pi,2*pi/364))*10+100) p1 <- ggplot(data=LakeLevels) + geom_line(aes(x=Elevation,y=Day)) + scale_x_continuous(name="Elevation (m)",limits=c(75,125)) p2<-ggplot(data=LakeLevels)+geom_line(aes(x=Elevation, y=Day))+ scale_x_continuous(name="Elevation (ft)", limits=c(75,125), breaks=c(80,90,100,110,120), labels=c("262", "295", "328", "361", "394")) #extract gtable g1<-ggplot_gtable(ggplot_build(p1)) g2<-ggplot_gtable(ggplot_build(p2)) #overlap the panel of the 2nd plot on that of the 1st plot pp<-c(subset(g1$layout, name=="panel", se=t:r)) g<-gtable_add_grob(g1, g2$grobs[[which(g2$layout$name=="panel")]], pp$t, pp$l, pp$b, pp$l) ia <- which(g2$layout$name == "axis-b") ga <- g2$grobs[[ia]] ax <- ga$children[[2]] ax$widths <- rev(ax$widths) ax$grobs <- rev(ax$grobs) ax$grobs[[1]]$x <- ax$grobs[[1]]$x - unit(1, "npc") + unit(0.15, "cm") g <- gtable_add_cols(g, g2$widths[g2$layout[ia, ]$l], length(g$widths) - 1) g <- gtable_add_grob(g, ax, pp$t, length(g$widths) - 1, pp$b) # draw it grid.draw(g) 

Esto produce un nuevo eje x, pero hay un par de problemas: 1) está en el medio de la gráfica 2) no produce una nueva etiqueta x para “Elevación (pies)”

Necesito que el eje aparezca en la parte superior del gráfico, y necesito una etiqueta de eje asociada. ¿Alguien puede decirme qué estoy haciendo mal?

Además, como se mencionó anteriormente, estoy trabajando con datos de temperatura a escala, por lo que idealmente las marcas no se alinearían en los ejes superior e inferior como lo hacen en este ejemplo. ¿Hay alguna manera de hacer esto en ggplot2? Un ejemplo arbitrario de la web es este:

Dos ejes x con diferentes escalas

La raíz de su problema es que está modificando columnas y no filas.

La configuración, con tags escaladas en el eje X de la segunda gráfica:

 ## 'base' plot p1 <- ggplot(data=LakeLevels) + geom_line(aes(x=Elevation,y=Day)) + scale_x_continuous(name="Elevation (m)",limits=c(75,125)) ## plot with "transformed" axis p2<-ggplot(data=LakeLevels)+geom_line(aes(x=Elevation, y=Day))+ scale_x_continuous(name="Elevation (ft)", limits=c(75,125), breaks=c(90,101,120), labels=round(c(90,101,120)*3.24084) ## labels convert to feet ) ## extract gtable g1 <- ggplot_gtable(ggplot_build(p1)) g2 <- ggplot_gtable(ggplot_build(p2)) ## overlap the panel of the 2nd plot on that of the 1st plot pp <- c(subset(g1$layout, name=="panel", se=t:r)) g <- gtable_add_grob(g1, g2$grobs[[which(g2$layout$name=="panel")]], pp$t, pp$l, pp$b, pp$l) 

EDITAR para que las líneas de la cuadrícula se alineen con las g <- gtable_add_grob(g1, g1$grobs[[which(g1$layout$name=="panel")]], pp$t, pp$l, pp$b, pp$l) eje inferior, reemplace la línea anterior con: g <- gtable_add_grob(g1, g1$grobs[[which(g1$layout$name=="panel")]], pp$t, pp$l, pp$b, pp$l)

 ## steal axis from second plot and modify ia <- which(g2$layout$name == "axis-b") ga <- g2$grobs[[ia]] ax <- ga$children[[2]] 

Ahora, necesita asegurarse de que está modificando la dimensión correcta. Como el nuevo eje es horizontal (una fila y no una columna), whatever_grob$heights es el vector que se debe modificar para cambiar la cantidad de espacio vertical en una fila determinada. Si desea agregar espacio nuevo, asegúrese de agregar una fila y no una columna (es decir, use gtable_add_rows() ).

Si está modificando los grobs (en este caso estamos cambiando la justificación vertical de los tics), asegúrese de modificar y (posición vertical) en lugar de x (posición horizontal).

 ## switch position of ticks and labels ax$heights <- rev(ax$heights) ax$grobs <- rev(ax$grobs) ax$grobs[[2]]$y <- ax$grobs[[2]]$y - unit(1, "npc") + unit(0.15, "cm") ## modify existing row to be tall enough for axis g$heights[[2]] <- g$heights[g2$layout[ia,]$t] ## add new axis g <- gtable_add_grob(g, ax, 2, 4, 2, 4) ## add new row for upper axis label g <- gtable_add_rows(g, g2$heights[1], 1) g <- gtable_add_grob(g, g2$grob[[6]], 2, 4, 2, 4) # draw it grid.draw(g) 

gtable_show_layout() paso que gtable_show_layout() es una función muy, muy útil para descubrir qué está pasando.