Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

insetting on 'facet_grid'ed and 'grid.arrange'ed plot

Tags:

r

ggplot2

I am trying to create a 2 faceted ggplot objects, and grid.arrange them in two columns (grid.arrange columns). In the second column, in each faceted member, I would like to inset a histogram. The data sources for the two columns are also different. So far I can only manage to grid arrange two faceted ggplot object. I need to know how to inset in the second column of grid.arrange.

Following code is a very simplistic representation of my data.

#Two data sources (d1,d2). They will have even different facetting parameters as well, 
#but here I have simplified it.

d1<-data.frame(FacetRow=c(rep('a',4),rep('b',4)),
           FacetCol=rep(c(rep('c',2),rep('d',2)),2),
           X=rep(c(1,2),4),
           Y=runif(8)
           )
d2<-data.frame(FacetRow=c(rep('a',4),rep('b',4)),
               FacetCol=rep(c(rep('c',2),rep('d',2)),2),
               X=rep(c(1,2),4),
               Y=runif(8)
)

#GGPlot object for First column of grid.arrange
g.col.1<-ggplot(data=d1,aes(x=X,y=Y))+geom_line()+facet_grid(FacetRow~FacetCol)
#GGPlot object for Second column of grid.arrange
g.col.2<-ggplot(data=d2,aes(x=X,y=Y))+geom_line()+facet_grid(FacetRow~FacetCol)
grid.arrange(g.col.1,g.col.2,ncol=2)

This is how it looks. So I just need to know how to inset a histogram of values in each of the (e,f,g)X(h,i) plots.

Further, I need to keep plotting this on different pages of a pdf by varying the d1 and d2. So I think I can only print the finally created ggplot object once, and then change d1 & d2 and then print again, and so on.

Will be grateful if anyone can help with this problem.

Many thanks

like image 846
piyush mishra Avatar asked Dec 02 '25 09:12

piyush mishra


1 Answers

annotation_custom would be convenient, unfortunately it's not meant to place different grobs in different panels (don't ask me). This minimal change works around that,

library(ggplot2)
library(gridExtra)
annotation_custom2 <- function (grob, xmin = -Inf, xmax = Inf, ymin = -Inf, ymax = Inf, data) 
  {
    layer(data = data, stat = StatIdentity, position = PositionIdentity, 
          geom = ggplot2:::GeomCustomAnn,
          inherit.aes = TRUE, params = list(grob = grob, 
                                            xmin = xmin, xmax = xmax, 
                                            ymin = ymin, ymax = ymax))
  }

inset <- qplot(rnorm(10))

p1 <- ggplot(data=d1,aes(x=X,y=Y))+geom_line()+facet_grid(FacetRow~FacetCol)
p2 <- ggplot(data=d2,aes(x=X,y=Y))+geom_line()+facet_grid(FacetRow~FacetCol) +
  annotation_custom2(ggplotGrob(inset), data=data.frame(FacetRow="b", FacetCol = "c", X=1, Y=1),
                     xmin=-Inf, xmax=1.5, ymin=-Inf, ymax=0.6)

grid.arrange(p1, p2, ncol=2)

enter image description here

Note: you could use plyr to generate those annotation layers automatically, e.g.

library(plyr)

insets <- dlply(d2, c("FacetRow", "FacetCol"), function(d){
  annotation_custom2(grob = ggplotGrob(qplot(d$Y) + 
                                         ggtitle(sprintf("col: %s\nrow: %s", 
                                                         unique(d$FacetCol), unique(d$FacetRow)))), 
                     data = data.frame(X=min(d$X), Y=min(d$Y), 
                                       FacetRow=unique(d$FacetRow), 
                                       FacetCol=unique(d$FacetCol)), 
                     xmin=-Inf, xmax=1.5, ymin=-Inf, ymax=0.6)
})

p1 <- ggplot(data=d1,aes(x=X,y=Y))+geom_line()+facet_grid(FacetRow~FacetCol)
p2 <- ggplot(data=d2,aes(x=X,y=Y))+geom_line()+facet_grid(FacetRow~FacetCol) +
  insets

grid.arrange(p1, p2, ncol=2)

enter image description here

like image 161
baptiste Avatar answered Dec 03 '25 22:12

baptiste



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!