R 中的嵌套布局 [英] Nested layouts in R

查看:41
本文介绍了R 中的嵌套布局的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to make a plot consisting of multiple plots consisting of multiple plots, say a 5x2 grid with three plots in each cell. To be more precise, what I need is not just one figure but finding a way of using my plotting function multiple times in a single plot.

我编写了一个函数,它使用布局来堆叠绘图,在外边距中有一个公共轴.对于 TraMineR 包中的 seqIplot 和 seqdplot 函数,我实际上需要它,但据我所知,问题与这些无关,因此这是一个使用 barplot 的最小工作示例.

I have written a function that uses layout to stack plots, with a common axis in outer margin. I actually need it for seqIplot and seqdplot functions from the TraMineR package, but as far as I understand the problem is not related to those, 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)))

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

What I would like to do is to then use something like layout again and use stackedplot for the grids of the layout, 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))

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

I have tried split.screen, with no 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 包,但显然它与基本图形不兼容.

I also tried grid package, but apparently it is not compatible with base graphics.

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)

推荐答案

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

After more research and some help I am now answering my own question in case it would be useful to someone else.

可以使用 grid 包创建嵌套布局,该包可用于使用 gridBase 包的基础图形.堆积图的函数写成如下.

Nested layouts can be created with the grid package, which can be used for base graphics using the gridBase package. The function for the stacked plots is written as follows.

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 进行绘图了.

The function first describes a viewport (of 90% of the window's width) that is divided into a 5x1 grid of viewports with differing heights. Each viewport in the grid is given a name that can be later called. The tree of viewports (splot) is described with vpTree which defines the hierarchical structure of the viewports. After describing the viewports those are actually prepared for plotting with pushViewport.

现在首先寻找每个命名的视口,然后打开以使用 upViewport(在视口树中向上)和 downViewport(向下寻找请求的视口)进行绘图在视口树中).

Now each named viewport is first seeked and then opened for plotting with upViewport (which goes up in the viewport tree) and downViewport (which seeks for the requested viewport down in the viewport tree).

为了绘制基础图形,这里需要gridPLT(或者可以使用gridFIGgridOMI,更多信息请参见gridBase 的手册)).之后,任何基础图形函数都可以用于绘制到当前视口中.

For plotting base graphics, gridPLT is needed here (alternatively gridFIG or gridOMI can be used, see the manual of gridBase for further info). After that any base graphics function can be used to plot into the current viewport.

在请求的绘图之后,upViewport(2) 用于导航回根(层次结构中向上的 2 个视口).

After the requested plots, upViewport(2) is used to navigate back to the root (2 viewports up in the hierarchy).

现在可以在另一个网格中多次调用stackedplot函数,如下所示.

Now the stackedplot function can be called multiple times in another grid as follows.

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

这篇关于R 中的嵌套布局的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆