R中的嵌套布局

R中的嵌套布局,r,plot,R,Plot,我想做一个由多个图组成的图,比如一个5x2的网格,每个单元格有三个图。更准确地说,我需要的不仅仅是一个图形,而是找到一种在一个绘图中多次使用绘图功能的方法 我编写了一个函数,它使用布局来堆叠绘图,在外缘有一个公共轴。实际上,我需要它用于TraMineR包中的seqIplot和seqdplot函数,但据我所知,问题与这些函数无关,因此这里是一个使用barplot的最小工作示例 stackedplot <- function(data){ layout(matrix(c(1:3), nro

我想做一个由多个图组成的图,比如一个5x2的网格,每个单元格有三个图。更准确地说,我需要的不仅仅是一个图形,而是找到一种在一个绘图中多次使用绘图功能的方法

我编写了一个函数,它使用布局来堆叠绘图,在外缘有一个公共轴。实际上,我需要它用于TraMineR包中的seqIplot和seqdplot函数,但据我所知,问题与这些函数无关,因此这里是一个使用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)))
我尝试过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)

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

嵌套布局可以使用
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)
}
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

AFAIK,嵌套的
布局
s是不可能的。和
split.screen
被记录为不与
layout
混合。如果问题来自TraMineR,您可以使用seqIplot(group=NULL,withlegend=FALSE),TraMineR将不会调用layout命令。谢谢,Matthias。然而,问题似乎与TraMineR没有直接关系,而是与所有(基本)图形有关。目前,gridBase软件包在绘制“嵌套布局”方面看起来很有希望。一个更新的、也许有用的替代品是gridGraphics软件包,其中
grid.echo
生成了基于网格的基本图形版本。
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