R Question

Multiple grid.draw plots with a function for plotting

I have data frame on this link (file name =Fish11a.rda)

load("Fish11a.rda")
df=Fish11a
df=data.frame(Time=as.factor(df[,6]),RoiID=df[,3],Diameter=df[,8])
df$Time.hours=rep(1:10,each=104*max(df$RoiID),len=nrow(df))
df$Time <- factor(df$Time, levels=rev(levels(df$Time)))
df1=split(df,df$Time.hours)


Now I have 10 data frames from
df1: df1$"1",df1$"2",.....,df1$"10"


Then a wrote a function
hle1
to make plots from that data:



hle1=function(dfr,br,tenplot,tenfile) {
require(ggplot2)
require(gtable)
library(grid)
bre=lapply(split(df,df$Time.hours), function(x) {
br=data.frame(x[c(1,round(nrow(x)*(1:4)/4)),])
br$Min=c(0,15,30,45,60)
return(br)
})
#start plot
g=ggplot(data=dfr, aes(x=factor(RoiID), y=Time, fill = Diameter)) +
theme_minimal() + coord_fixed(ratio=1) +
geom_tile(colour = NA, width = 1.5, height = 1)+
scale_fill_gradient(low="black",high="white")+
theme(axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank())+
scale_x_discrete(expand = c(0,0))+
scale_y_discrete(name="Time (min)",
expand = c(0,0),
breaks=br$Time,labels=br$Min)+
theme(axis.ticks.length = unit(0, "lines"))+
ggtitle(tenplot)

# calculate segment coordinates
segs <- c(.39, .23, .23, .15)
segs_center <- cumsum(segs) - segs/2
seg_ticks <- cumsum(segs)[1:3]
seg_labels <- paste("Seg", seq_along(segs))

# create graphicaal objects and gather as tree
grobs <- grobTree(linesGrob(c(0,1), c(-1,-1),gp=gpar(lwd=3)),
segmentsGrob(x0=seg_ticks, x1=seg_ticks, y0=0, y1=-4,gp=gpar(lwd=3)),
textGrob(x=segs_center, y=-3.5,
label = seg_labels, hjust = .5, gp = gpar(cex =.9)))

# insert grobsTree in as annotation
g <- g + annotation_custom( grob = grobs,
ymin = -.3, ymax = 0.2,
xmin = .25, xmax = max(dfr$RoiID))

# override clipping for plotting outside of plotting area
gt <- ggplot_gtable(ggplot_build(g))
gt$layout$clip[gt$layout$name == "panel"] <- "off"
grid.newpage()
grid.draw(gt)}





I will use the function
hle1
to make plot for the ten data frames above (df1$"1",...,df1$"10")

And then, I want to put 10 plots made into one figure by grid.arrange and save as a tiff.file



tiff(file="test11.tiff", width = 17,height=30, units = 'cm', res = 300)
require(gridExtra)
grid.arrange(hle1(df1$"1",bre$`1`,c("1 hour-feed")),
hle1(df1$"2",bre$`2`,c("2 hours-feed")),
hle1(df1$"3",bre$`3`,c("3 hours-feed")),
hle1(df1$"4",bre$`4`,c("4 hours-feed")),
hle1(df1$"5",bre$`5`,c("5 hours-feed")),
hle1(df1$"6",bre$`6`,c("6 hours-feed")),
hle1(df1$"7",bre$`7`,c("7 hours-feed")),
hle1(df1$"8",bre$`8`,c("8 hours-feed")),
hle1(df1$"9",bre$`9`,c("9 hours-feed")),
hle1(df1$"10",bre$`10`,c("10 hours-feed")),
ncol=5,top="Fish 11 - feed")
dev.off()





But I got only one plots from df1$"10".
Does any of you know why? I appreciate your value time on my long question.

Answer

I see several issues in your code. The bre variable is passed on the hle1 function but only seems to be calculated inside that function. Another issue is that you don't return the result of the hle1 function but rather plot it inside that function. If you replace grid.draw(gt) with gt you code may work.

This is the code that I updated and which worked for me:

load("Fish11a.rda")
df=Fish11a
df=data.frame(Time=as.factor(df[,6]),RoiID=df[,3],Diameter=df[,8])
df$Time.hours=rep(1:10,each=104*max(df$RoiID),len=nrow(df))
df$Time <- factor(df$Time, levels=rev(levels(df$Time)))
df1=split(df,df$Time.hours)

hle1=function(dfr,tenplot) {
  require(ggplot2)
  require(gtable)
  library(grid)
  br=lapply(split(df,df$Time.hours), function(x) {
    br=data.frame(x[c(1,round(nrow(x)*(1:4)/4)),])
    br$Min=c(0,15,30,45,60)
    return(br)
  })
  #start plot
  g=ggplot(data=dfr, aes(x=factor(RoiID), y=Time, fill = Diameter)) +
    theme_minimal()  + coord_fixed(ratio=1) +
    geom_tile(colour = NA, width = 1.5, height = 1)+ 
    scale_fill_gradient(low="black",high="white")+
    theme(axis.title.x=element_blank(),
          axis.text.x=element_blank(),
          axis.ticks.x=element_blank())+
    scale_x_discrete(expand = c(0,0))+
    scale_y_discrete(name="Time (min)",
                     expand = c(0,0),
                     breaks=br$Time,labels=br$Min)+
    theme(axis.ticks.length = unit(0, "lines"))+
    ggtitle(tenplot)

  # calculate segment coordinates
  segs <- c(.39, .23, .23, .15)
  segs_center <- cumsum(segs) - segs/2
  seg_ticks <- cumsum(segs)[1:3]
  seg_labels <- paste("Seg", seq_along(segs))

  # create graphicaal objects and gather as tree
  grobs <- grobTree(linesGrob(c(0,1), c(-1,-1),gp=gpar(lwd=3)),
                    segmentsGrob(x0=seg_ticks, x1=seg_ticks, y0=0, y1=-4,gp=gpar(lwd=3)),
                    textGrob(x=segs_center, y=-3.5, 
                             label = seg_labels, hjust = .5, gp = gpar(cex =.9)))

  # insert grobsTree in as annotation
  g <- g + annotation_custom( grob = grobs,  
                              ymin = -.3, ymax = 0.2, 
                              xmin = .25, xmax = max(dfr$RoiID))

  # override clipping for plotting outside of plotting area
  gt <- ggplot_gtable(ggplot_build(g))
  gt$layout$clip[gt$layout$name == "panel"] <- "off"
  grid.newpage()
  #grid.draw(gt)
  gt
}
#Run code snippetCopy snippet to answerExpand snippet
#I will use the function "hle1" to make plot for the ten data frames above (df1$"1",...,df1$"10") And then, I want to put 10 plots made into one figure by grid.arrange and save as a tiff.file

tiff(file="test11.tiff", width = 17,height=30, units = 'cm', res = 300)
require(gridExtra)   
grid.arrange(hle1(df1$"1",c("1 hour-feed")),
             hle1(df1$"2",c("2 hours-feed")),
             hle1(df1$"3",c("3 hours-feed")),
             hle1(df1$"4",c("4 hours-feed")),
             hle1(df1$"5",c("5 hours-feed")),
             hle1(df1$"6",c("6 hours-feed")),
             hle1(df1$"7",c("7 hours-feed")),
             hle1(df1$"8",c("8 hours-feed")),
             hle1(df1$"9",c("9 hours-feed")),
             hle1(df1$"10",c("10 hours-feed")),
             ncol=5,top="Fish 11 - feed")
dev.off()

#Run code snippetCopy snippet to answer

You may also want to look into facet grid for combining plots inside ggplot: http://docs.ggplot2.org/current/facet_grid.html

Comments