我想制作一个由多个图组成的图,包括一个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)
答案 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
(或者可以使用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