2011-09-14 11 views
6

Tengo un diagrama de línea ggplot2 con un número impar de facetas. Me gustaría agregar un diagrama de caja de la distribución marginal de los valores x en el espacio vacío. El diagrama de caja debe ser horizontal y compartir un eje x común con las otras facetas. Debido a que el diagrama de caja predeterminado geom es vertical, se requiere coord_flip(). Debido a esto, no creo que sea posible incluir los datos de la gráfica de caja en el mismo df como las otras facetas usando una variable de factor ficticio para facetar.Alinear ejes ggplot2 usando la cuadrícula

Usando grid, puedo identificar la ventana vacía e insertar el diagrama de caja, pero quiero que los ejes x estén alineados. Las respuestas a preguntas similares (ver here o here) sugieren usar align_plots en el paquete ggExtra, pero no creo que funcione con la facetación. He incluido un ejemplo reproducible simple a continuación. Si logro que esto funcione, también tendría que editar el Grob del panel vacío para crear una nueva etiqueta que coincida con las otras facetas. Cualquier sugerencia sera apreciada.

library(ggplot2) 
#generate df for faceted line graphs 
df <- data.frame(x = rep(1:100, times=7), 
     facet_var = as.factor(rep(1:7, each=100)), 
     y = runif(7*100) 
    ) 
#create faceted line graphs 
p <- ggplot(data = df, aes(x, y)) + 
    geom_line() + facet_wrap(~ facet_var, ncol=2) 

#generate df for boxplot 
xdata <- runif(1000, min = 0, max = 100) 
boxdf <- data.frame(x=xdata, group=rep(1,length(xdata))) 

#create boxplot removing axes and margins 
q <- ggplot(data = boxdf, aes(as.factor(group),x)) + geom_boxplot() + 
     coord_flip() + labs(x=NULL) + 
     opts(axis.text.x = theme_blank(), axis.title.x=theme_blank(), 
     axis.text.y = theme_blank(), axis.title.y=theme_blank(), 
     axis.ticks = theme_segment(colour = "white"), 
     panel.margin = 0, plot.margin = unit(rep(0,4), "lines") 
     ) 

print(p) 
downViewport("panel-14-5") 
print(q, newpage=F) 

Editar : Después de respuesta es útil kohske, he tratado de adaptar el código para diferentes límites X y se rompe. Aquí está el código con solo los límites xy las interrupciones alteradas para un rango de (0,80). Posiblemente me falta algo en el código que debe modificarse con los límites.

library(ggplot2) 
df <- data.frame(x = rep(1:80, times=7), 
     facet_var = as.factor(rep(1:7, each=80)), 
     y = runif(7*80) 
    ) 

# label for marginal plot 
df <- rbind(df, data.frame(x = NA, y = NA, facet_var = "Boxplot wow")) 

p <- ggplot(data = df, aes(x, y)) + 
    geom_line() + facet_wrap(~ facet_var, ncol=2) + 
    # set limits for adjustment 
    coord_cartesian(xlim = c(0, 80)) + 
    #scale_x_continuous(breaks = 1:4*20) 
    opts() 

xdata <- runif(1000, min = 0, max = 80) 
boxdf <- data.frame(x=xdata, group=rep(1,length(xdata))) 

q <- ggplot(data = boxdf, aes(as.factor(group),x)) + geom_boxplot() + 

    # set breaks and limits for adjustment 
    coord_flip(ylim = c(0, 80)) + labs(x=NULL) + 
    scale_y_continuous(breaks = 1:4*20) + 

    # opts for full region drawing: 
    # see https://kohske.wordpress.com/2010/12/25/drawing-on-full-region-in-ggplot2/ 
    opts(
    legend.position = "none", 
    panel.margin = unit(0,"null"), 
    plot.margin = rep(unit(0,"null"),4), 
    axis.ticks = theme_blank(), 
    axis.text.x = theme_blank(), 
    axis.text.y = theme_blank(), 
    axis.title.x = theme_blank(), 
    axis.title.y = theme_blank(), 
    axis.ticks.length = unit(0,"null"), 
    axis.ticks.margin = unit(0,"null") 
) 

print(p) 

# remove unused panel 
grid.remove("panel-14-5") 

downViewport("panel-14-5") 
print(q, newpage=F) 

enter image description here

Respuesta

7

aquí es un truco poco sucia:

library(ggplot2) 
df <- data.frame(x = rep(1:100, times=7), 
     facet_var = as.factor(rep(1:7, each=100)), 
     y = runif(7*100) 
    ) 

# label for marginal plot 
df <- rbind(df, data.frame(x = NA, y = NA, facet_var = "Boxplot wow")) 

p <- ggplot(data = df, aes(x, y)) + 
    geom_line() + facet_wrap(~ facet_var, ncol=2) + 
    # set limits for adjustment 
    coord_cartesian(xlim = c(0, 100)) 

xdata <- runif(1000, min = 20, max = 80) 
boxdf <- data.frame(x=xdata, group=rep(1,length(xdata))) 

q <- ggplot(data = boxdf, aes(as.factor(group),x)) + geom_boxplot() + 

    # set breaks and limits for adjustment 
    coord_flip(ylim = c(0, 100)) + labs(x=NULL) + 
    scale_y_continuous(breaks = 1:5*20) + 

    # opts for full region drawing: 
    # see https://kohske.wordpress.com/2010/12/25/drawing-on-full-region-in-ggplot2/ 
    opts(
    legend.position = "none", 
    panel.margin = unit(0,"null"), 
    plot.margin = rep(unit(0,"null"),4), 
    axis.ticks = theme_blank(), 
    axis.text.x = theme_blank(), 
    axis.text.y = theme_blank(), 
    axis.title.x = theme_blank(), 
    axis.title.y = theme_blank(), 
    axis.ticks.length = unit(0,"null"), 
    axis.ticks.margin = unit(0,"null") 
) 

print(p) 

# remove unused panel 
grid.remove("panel-14-5") 

downViewport("panel-14-5") 
print(q, newpage=F) 

enter image description here

+0

Esto hace exactamente lo que necesito. ¡Gracias! ¿Alguna vez las opciones de dibujo de la región completa se incorporaron como tema en 'ggExtra'? – Sandy

+0

Aquí hay una colección de temas contribuidos. https://github.com/hadley/ggplot2/wiki/Themes No estoy seguro si estos se importan en ggExtra. – kohske

+0

@Sandy hay 'opts_full' http://ggextra.googlecode.com/svn/trunk/R/themes.r pero' ggExtra' no debería estar disponible por mucho tiempo, con suerte. – baptiste

Cuestiones relacionadas