ali*_*boy 19 layout plot r heatmap
通过使用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`?
Run Code Online (Sandbox Code Playgroud)
我使用包中的heatmap.2函数gplots来生成热图.以下是单个热图的示例代码:
library(gplots)
row.scaled.expr <- matrix(sample(1:10000),nrow=1000,ncol=10)
heatmap.2(row.scaled.expr, 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(row.scaled.expr),
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 ),
)
Run Code Online (Sandbox Code Playgroud)
但是,由于我想在单个图中比较多个热图,我使用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 ),
)
Run Code Online (Sandbox Code Playgroud)
但是,结果不是单个图中的四个热图,而是四个单独的热图.换句话说,如果我pdf()用来输出结果,则文件是四页而不是一页.我需要在某处更改任何参数吗?非常感谢!
Din*_*nre 19
好的.我想这个问题一直没有得到答复,应该写下长篇答案.
最困难的图形问题的答案是(如@backlin所建议的)'网格'包的原始使用.许多预构建的图形包会覆盖所有当前视口和绘图设备设置,因此如果您想要以非常特定的方式完成某些操作,则必须自己构建它.
我建议选择Paul Murrell的书"R Graphics"并翻阅'grid'包中的章节.这是一本疯狂有用的书,我的桌子上随时都有副本.
对于你的热图,我写了一本快速入门书,可以让你快速入门.
要知道的功能
grid.newpage() 这初始化了绘图设备.不带参数使用它.grid.rect() 这画一个矩形.你的热图基本上只是一组巨大的彩色矩形,所以这将是你的大部分图形.它的工作原理如下:grid.rect(x=x_Position, y=y_Position, width=width_Value, height=height_Value, gp=gpar(col=section_Color, fill=section_Color), just=c("left", "bottom"), default.units="native") 'just'参数指定矩形的哪个点将位于指定的(x,y)坐标上.grid.text() 这绘制文本.它的工作原理如下:grid.text("Label Text", x_Value, y_Value, gp=gpar(col=color_Value, cex=font_Size), just=c("right","center"), rot=rot_Degrees, default.units="native")grid.lines() 这画了一条线.它的工作原理如下:grid.lines(c(x_Start,x_End), c(y_Start, y_End), gp=gpar(col=color_Value), default.units="native")dataViewport() 这定义了绘图窗口的属性,"网格"指的是"视口".像这样使用它:pushViewport(dataViewport(xData=x_Data, yData=y_Data, xscale=c(x_Min, x_Max), yscale=c(y_Min, y_Max), x=x_Value, y=y_Value, width=width_Value, height=height_Value, just=c("left","center"))) 这里要记住一些东西......请参阅视口的更详细说明.pushViewport() 这用于初始化veiwport.您将它包装在视口定义周围以实际执行视口,如下所示:pushViewport(dataViewport([stuff in here]))popViewport() 这将最终确定一个视口,并在视口层次结构中向上移动一级.请参阅视口的更详细说明.简而言之,视口
视口是临时绘图空间,用于定义"网格"对象的绘制位置和方式.视口内的所有内容都是相对于视口绘制的.如果旋转视口,则内部的所有内容都将旋转.视口可以嵌套,可以重叠,几乎无限灵活,但有一个例外:它们总是一个矩形.
最初让很多人迷惑的是坐标系.每个视口(包括初始的'grid.newpage()'视口)在x和y轴上都从0到1.原点(0,0)是最左下角,最大(1,1)是最右上角.这是"npc"单位系统,并且没有指定一组单位的所有内容都可能最终根据此系统绘制.这对您来说意味着两件事:
viewport(x=0, y=0, width=0.5, height=1, just=c("left","lower")) 和 viewport(x=0.5, y=0, width=0.5, height=1, just=c("left","lower"))default.units="native"会告诉该点使用视口自己的坐标系并正确绘制点.可以直接导航和写入视口,但除非您执行非常自动化的操作,否则更容易指定视口,在其中绘制,然后"弹出"(完成)视口.这会返回到父视口,您可以从下一个视口开始.弹出每个视口是一种无杂乱的方法,适合大多数目的(并使调试更容易!).
绘制图形时,'dataViewport'功能非常重要.这是一种特殊类型的视口,可以为您处理所有坐标和比例,只要您告诉它您正在使用哪些数据.这是我用于任何绘图区域的那个.当我第一次开始使用'grid'包时,我调整了所有值以适应"npc"坐标系,但这是一个错误!只要你记得为每个绘图项使用"原生"单位,'dataViewport'功能就很容易.
放弃
数据可视化是我的强项,我不介意花半天时间编写一个良好的视觉效果.'grid'包允许我比我发现的任何其他东西更快地创建非常复杂的视觉效果.我将我的视觉效果编写为函数,因此我可以快速加载各种数据.我不能幸福.
但是,如果你不喜欢编写脚本,'grid'将是你的敌人.此外,如果你考虑半天的时间来进行视觉,那么'网格'对你来说太过分了.(in)着名的'ggplot2'包是大多数人都喜欢的,我衷心推荐它,尽管我个人并不认为它有用.
如果有人想要帮助学习'网格'图形,我非常愿意帮助教学.它彻底改变了我创建快速,智能和美观数据视觉的能力.
该gridGraphics包可能帮助,
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)
Run Code Online (Sandbox Code Playgroud)