Nested layouts in R

I want to make a plot consisting of several graphs consisting of several graphs, say a 5x2 grid with three graphs in each cell. To be more precise, I need not only one figure, but also a search for a way to use the graphing function several times in one plot.

I wrote a function that uses a layout for plotting, with a common axis in the outer edge. I really need this for the seqIplot and seqdplot functions from the TraMineR package, but as far as I understand, the problem is not related to them, so here is a minimal working example with barplot.

stackedplot <- function(data){
  layout(matrix(c(1:3), nrow=3))
    par(mar=c(0,0,0,0), oma=c(4,1,1,1), mgp=c(3,0.5,0), cex=1)
    barplot(data[[1]], axes=F, xlab="", ylab="", horiz=TRUE)
    barplot(data[[2]], axes=F, xlab="", ylab="", horiz=TRUE)
    barplot(data[[3]], axes=F, xlab="", ylab="", horiz=TRUE)
    axis(1, at=c(0:10)/10, outer=TRUE)
    mtext("Label", line=2, side=1)
}
stackedplot(list(1:10, 10:1, rep(1,10)))

What I would like to do is to use something like layout again and use stackedplot for layout grids, i.e. something like this (which of course does not work):

layout(matrix(c(1:2), nrow=1))
stackedplot(list(1:10, 10:1, rep(1,10)))
stackedplot(list(rep(1,10), 1:10, 10:1))

I tried split.screen, without success:

split.screen(c(1,2))
screen(1)
stackedplot(list(1:10, 10:1, rep(1,10)))
screen(2)
stackedplot(list(rep(1,10), 1:10, 10:1))
close.screen(all = TRUE)

grid, , -, .

grid.newpage()
pushViewport(viewport(x=0, y=0, width=0.5, height=1, 
                          default.units="native"))
print(stackedplot(list(1:10, 10:1, rep(1,10))), newpage=FALSE)
pushViewport(viewport(x=0.5, y=0, width=0.5, height=1,
                      default.units="native"))
print(stackedplot(list(rep(1,10), 1:10, 10:1)), newpage=FALSE)
+4
1

, - .

grid, gridBase. .

library(grid)
library(gridBase)

stackedplot <- function(data, main=""){

  top.vp <- viewport(layout=grid.layout(nrow=5, ncol=1, 
                                        heights=unit(c(3, 1, 1, 1, 5), 
                                                     c("lines", "null", "null", "null", "lines"))),
                     width=unit(0.9, "npc"))

  title <- viewport(layout.pos.row=1, layout.pos.col=1, name="title")
  p1 <- viewport(layout.pos.row=2, layout.pos.col=1, name="plot1")
  p2 <- viewport(layout.pos.row=3, layout.pos.col=1, name="plot2")
  p3 <- viewport(layout.pos.row=4, layout.pos.col=1, name="plot3")
  xaxis <- viewport(layout.pos.row=5, layout.pos.col=1, name="xaxis")

  splot <- vpTree(top.vp, vpList(title, p1, p2, p3, xaxis)) # Defining the hierarchy of the viewports
  pushViewport(splot) # Creating viewports for plotting with the definitions of splot

  upViewport() # Navigating up in the viewport tree
  downViewport("plot1") # Navigating down in the viewport tree, searching for viewport "plot1"
  grid.rect() # Plotting a rectangle (borders for the viewport)
  par(plt=gridPLT(), new=TRUE) # Taking the dimensions of the viewport for a base graphics plot
                               # Adding plot to an existing plot
  barplot(data[[1]], axes=FALSE, xlab="", ylab="", horiz=TRUE)

  upViewport()
  downViewport("plot2")
  grid.rect()
  par(plt=gridPLT(), new=TRUE)
  barplot(data[[2]], axes=FALSE, xlab="", ylab="", horiz=TRUE)

  upViewport()
  downViewport("plot3")
  grid.rect()
  par(plt=gridPLT(), new=TRUE)
  barplot(data[[3]], xlab="", ylab="", horiz=TRUE)

  upViewport()
  downViewport("xaxis")
  grid.text("X label", y = unit(2, "lines"))

  upViewport()
  downViewport("title")
  grid.text(main, y = unit(1, "lines"))

  upViewport(2)
}

(90% ), 5x1 . , . (splot) vpTree, . pushViewport.

, upViewport ( ) downViewport ( ).

gridPLT ( gridFIG gridOMI, . gridBase ). .

upViewport(2) (2 ).

stackedplot .

opar <- par(no.readonly=TRUE) # Saving graphical parameters
plot.new() # Needed for par(new=TRUE) in stackedplot()

multitop.vp <- viewport(layout=grid.layout(1,2), width = unit(0.95, "npc"))
pl1 <- viewport(layout.pos.col=1, layout.pos.row=1, name="A")
pl2 <- viewport(layout.pos.col=2, layout.pos.row=1, name="B")
vpall <- vpTree(multitop.vp, vpList(pl1,pl2))
pushViewport(vpall)

upViewport()
downViewport("A")
stackedplot(data=list(1:10,10:1,rep(10,10)),main="A")

upViewport()
downViewport("B")
stackedplot(data=list(10:1,rep(10,10),1:10),main="B")

upViewport(2)
par(opar) # Returning the graphical parameters saved earlier

enter image description here

+2

All Articles