R 将多个复杂绘图组合为单个图形中的面板 @backlin介绍
通过使用R 将多个复杂绘图组合为单个图形中的面板 @backlin介绍,r,layout,plot,heatmap,R,Layout,Plot,Heatmap,通过使用layout或par(mfrow=…),可以将多个简单绘图组合为单个图形中的面板。但是,更复杂的绘图往往会在内部设置自己的面板布局,从而禁止将其用作面板。有没有办法创建嵌套布局并将复杂绘图封装到单个面板中 我觉得grid软件包可以实现这一点,例如,通过在单独的视口中绘制面板,但还没有弄清楚如何实现。下面是一个玩具示例来演示问题: my.plot <- function(){ a <- matrix(rnorm(100), 10, 10) plot.new()
layout
或par(mfrow=…)
,可以将多个简单绘图组合为单个图形中的面板。但是,更复杂的绘图往往会在内部设置自己的面板布局,从而禁止将其用作面板。有没有办法创建嵌套布局并将复杂绘图封装到单个面板中
我觉得grid
软件包可以实现这一点,例如,通过在单独的视口中绘制面板,但还没有弄清楚如何实现。下面是一个玩具示例来演示问题:
my.plot <- function(){
a <- matrix(rnorm(100), 10, 10)
plot.new()
par(mfrow=c(2,2))
plot(1:10, runif(10))
plot(hclust(dist(a)))
barplot(apply(a, 2, mean))
image(a)
}
layout(matrix(1:4, 2, 2))
for(i in 1:4) my.plot()
# How to avoid reseting the outer layout when calling `my.plot`?
但是,因为我想在一个绘图中比较多个热图,所以我使用par(mfrow=c(2,2))
然后调用heatmap.2
四次,即
row.scaled.expr <- matrix(sample(1:10000),nrow=1000,ncol=10)
arr <- array(data=row.scaled.expr, dim=c(dim(row.scaled.expr),4))
par(mfrow=c(2,2))
for (i in 1:4)
heatmap.2(arr[ , ,i], dendrogram ='row',
Colv=FALSE, col=greenred(800),
key=FALSE, keysize=1.0, symkey=FALSE, density.info='none',
trace='none', colsep=1:10,
sepcolor='white', sepwidth=0.05,
scale="none",cexRow=0.2,cexCol=2,
labCol = colnames(arr[ , ,i]),
hclustfun=function(c){hclust(c, method='mcquitty')},
lmat=rbind( c(0, 3), c(2,1), c(0,4) ), lhei=c(0.25, 4, 0.25 ),
)
row.scaled.expr正常。我想这个问题已经有足够长的时间没有得到回答了,所以应该写下详细的答案
最困难的图形问题的答案是(正如@backlin所建议的)原始使用“网格”包。许多预构建的图形包会覆盖所有当前视口和打印设备设置,因此,如果您希望以非常特定的方式完成某些操作,则必须自己构建
我建议你读一下保罗·穆雷尔的书《R图形》,并复习一下“网格”软件包中的章节。这是一本非常有用的书,我的书桌上一直放着一本
对于你的热图,我已经写了一个快速入门,可以让你快速入门
需要了解的功能
grid.newpage()
这将初始化打印设备。不带参数地使用它
grid.rect()
这将绘制一个矩形。你的热图基本上只是一组巨大的彩色矩形,所以这将是你的大部分图形。它的工作原理如下:grid.rect(x=x\u位置,y=y\u位置,width=width\u值,height=height\u值,gpar(col=section\u颜色,fill=section\u颜色),just=c(“left”,“bottom”),default.units=“native”)
just参数指定矩形的哪个点位于指定的(x,y)坐标上
grid.text()
这将绘制文本。它的工作原理如下:grid.text(“标签文本”,x\u值,y\u值,gp=gpar(col=color\u值,cex=font\u大小),just=c(“右”,“中”),rot=rot\u度,默认值。units=“native”)
grid.lines()
这画了一条线。它的工作原理如下:grid.line(c(x\u开始,x\u结束),c(y\u开始,y\u结束),gp=gpar(col=color\u值),default.units=“native”)
dataViewport()
这定义了打印窗口的属性,“网格”将其称为“视口”。使用方法如下:pushViewport(dataViewport(扩展数据=x_数据,yData=y_数据,xscale=c(x_最小,x_最大),yscale=c(y_最小,y_最大),x=x_值,y=y_值,宽度=宽度_值,高度_值,刚好=c(“左”,“中”))
这里有一些东西需要记住。。。请参见视口的更详细说明
pushViewport()
用于初始化静脉端口。您可以围绕视口定义来实际执行视口,如下所示:pushViewport(dataViewport([stuff in here]))
popViewport()
这将完成视口并将您在视口层次结构中上移一级。请参见视口的更详细说明
简单地说就是视口
视口是临时绘图空间,用于定义绘制“栅格”对象的位置和方式。视口中的所有内容都是相对于视口绘制的。如果视口旋转,则内部的所有内容都将旋转。视口可以嵌套,可以重叠,并且几乎无限灵活,但有一个例外:它们始终是矩形
一开始会把很多人搞糊涂的是坐标系。每个视口,包括初始的“grid.newpage()”视口,在x轴和y轴上都从0变为1。原点(0,0)是最左下角,最大值(1,1)是最右上角。这是“npc”单位制,没有指定单位集的所有东西都可能最终按照该制度绘制。这对你来说意味着两件事:
指定视口大小和位置时使用“npc”系统。只要假设您的视口必须使用“npc”坐标,就可以省去很多麻烦。这意味着,如果要相邻绘制两个打印,两个视口的定义如下所示:
视口(x=0,y=0,宽度=0.5,高度=1,刚度=c(“左”,“下”))
和
视口(x=0.5,y=0,宽度=0.5,高度=1,刚度=c(“左”,“下”))
如果视口具有不同的坐标系(例如用于绘制图形的视口),则需要为绘制的每个“栅格”对象指定“default.units”参数。例如,如果您试图在(2,4)处绘制一个点,您将永远看不到该点,因为它将远离屏幕。指定default.units=“native”
将告诉该点使用视口自己的坐标系,并将正确绘制该点
视口可以直接进行导航和写入,但除非您执行的是非常自动化的操作,否则指定视口、在其中绘制,然后“弹出”(最终确定)视口会更容易。这将返回到父视口,您可以从下一个视口开始。弹出每个视口是一种无杂乱的方法,适合大多数用途(并且更容易调试!)
绘制图形时,“dataViewport”功能非常重要。这是一种特殊类型的视口,可以为您处理所有坐标和比例,只要您告诉它您使用的是什么数据。这是我用于任何绘图区域的。当我第一次开始使用“网格”包时,我调整了所有的值以适应“npc”坐标
row.scaled.expr <- matrix(sample(1:10000),nrow=1000,ncol=10)
arr <- array(data=row.scaled.expr, dim=c(dim(row.scaled.expr),4))
par(mfrow=c(2,2))
for (i in 1:4)
heatmap.2(arr[ , ,i], dendrogram ='row',
Colv=FALSE, col=greenred(800),
key=FALSE, keysize=1.0, symkey=FALSE, density.info='none',
trace='none', colsep=1:10,
sepcolor='white', sepwidth=0.05,
scale="none",cexRow=0.2,cexCol=2,
labCol = colnames(arr[ , ,i]),
hclustfun=function(c){hclust(c, method='mcquitty')},
lmat=rbind( c(0, 3), c(2,1), c(0,4) ), lhei=c(0.25, 4, 0.25 ),
)
library(gplots)
row.scaled.expr <- matrix(sample(1:10000),nrow=1000,ncol=10)
arr <- array(data=row.scaled.expr, dim=c(dim(row.scaled.expr),4))
par(mfrow=c(2,2))
for (i in 1:4) {
ifile <- paste0(i,'_heatmap.pdf')
pdf(ifile)
heatmap.2(arr[ , ,i], dendrogram ='row',
Colv=FALSE, col=greenred(800),
key=FALSE, keysize=1.0, symkey=FALSE, density.info='none',
trace='none', colsep=1:10,
sepcolor='white', sepwidth=0.05,
scale="none",cexRow=0.2,cexCol=2,
labCol = colnames(arr[ , ,i]),
hclustfun=function(c){hclust(c, method='mcquitty')},
lmat=rbind( c(0, 3), c(2,1), c(0,4) ), lhei=c(0.25, 4, 0.25 ),
)
dev.off()
}
system('montage -geometry 100% -tile 2x2 ./*_heatmap.pdf outfile.pdf')
library(gridGraphics)
library(grid)
grab_grob <- function(){
grid.echo()
grid.grab()
}
arr <- replicate(4, matrix(sample(1:100),nrow=10,ncol=10), simplify = FALSE)
library(gplots)
gl <- lapply(1:4, function(i){
heatmap.2(arr[[i]], dendrogram ='row',
Colv=FALSE, col=greenred(800),
key=FALSE, keysize=1.0, symkey=FALSE, density.info='none',
trace='none', colsep=1:10,
sepcolor='white', sepwidth=0.05,
scale="none",cexRow=0.2,cexCol=2,
labCol = colnames(arr[[i]]),
hclustfun=function(c){hclust(c, method='mcquitty')},
lmat=rbind( c(0, 3), c(2,1), c(0,4) ), lhei=c(0.25, 4, 0.25 ),
)
grab_grob()
})
grid.newpage()
library(gridExtra)
grid.arrange(grobs=gl, ncol=2, clip=TRUE)