R中的嵌套布局

时间:2014-11-19 11:13:38

标签: r plot

我想制作一个由多个图组成的图,包括一个5x2网格,每个单元格中有三个图。更确切地说,我需要的不仅仅是一个数字,而是在一个地块中找到一种多次使用我的绘图功能的方法。

我编写了一个使用布局来叠加图形的函数,在外边距中有一个公共轴。我实际上需要它来自TraMineR包中的seqIplot和seqdplot函数,但据我所知,这个问题与那些无关,所以这里是一个带有条形图的最小工作示例。

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)))

我想要做的是再次使用类似布局的东西,并使用stackedplot作为布局的网格,即这样的东西(当然,这不起作用):

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))

我尝试过split.screen,但没有成功:

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.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)

1 个答案:

答案 0 :(得分:3)

经过更多的研究和一些帮助,我现在回答我自己的问题,以防对其他人有用。

可以使用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(或者可以使用gridFIGgridOMI,有关详细信息,请参阅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