将单个图形中的多个复杂图形组合为面板

引用by @backlin

通过使用布局或参数(mfrow = …),多个简单的图可以组合成单个图形中的面板。然而,更复杂的地块倾向于在内部禁用它们的面板布局。有没有办法创建一个嵌套的布局,并将一个复杂的图形封装到单个面板中?

我有一种感觉,网格包可以实现这一点,例如通过在独立的视口中绘制面板,但还没有弄清楚如何。这是玩具示例来说明问题:

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`?

@alittleboy的原始问题

我在gplots包中使用heatmap.2函数来生成热图。以下是单个热图的示例代码:

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 ),                 
)

然而,由于我想比较一个图中的多个热图,我使用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 ),                 
)

然而,结果不是单个图中的四个热图,而是四个单独的热图。换句话说,如果我使用pdf()输出结果,文件是四页而不是一页。我需要改变任何参数吗?非常感谢!

好的。我想这个问题一直没有得到答复,足够的时间才能写出长的答案。

对于最困难的图形问题的答案是(正如@backlin所说)“网格”软件包的原始使用。许多预构建的图形包覆盖所有当前的视口和绘图设备设置,所以如果你想要一个非常具体的方法,你必须自己建立它。

我建议拿起保罗·默雷尔(Paul Murrell)的书“R Graphics”,然后浏览“网格”包的章节。这是一本疯狂的有用的书,一个副本坐在我的桌子上。

对于您的热图,我已经写了一个快速的底漆,让您快速开始。

功能知道

> 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。单位=“天然的”)
> grid.lines()这画一条线。它的工作原理如下:grid.lines(c(x_Start,x_End),c(y_Start,y_End),gp = gpar(col = color_Value),default.units =“native”)
> dataViewport()这定义了绘图窗口的属性,“grid”指的是“viewport”。使用它像这样: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([在这里的东西)))
> popViewport()这将完成视口并将其移动到视口层次结构中的一个级别。查看更详细的视口说明。

视口简而言之

视口是临时绘图空间,用于定义“grid”对象的绘制位置和方式。视口内的所有内容都相对于视口绘制。如果视口旋转,内部的所有内容将被旋转。视口可以嵌套,可以重叠,几乎无限灵活,但有一个例外:它们总是一个矩形。

最初混乱了很多人的东西是坐标系。每个视口,包括初始的“grid.newpage()”视口,在x轴和y轴上都从0到1。原点(0,0)是最左下角,最大(1,1)是右上角的右上角。这是“npc”单位系统,所有没有指定单位的单位都可能会根据这个系统来绘制。这对你来说意味着两件事情:

>指定视口大小和位置时,请使用“npc”系统。只要假设你的视口必须使用“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”))

>如果您的视口具有不同的坐标系(例如绘制图形的视口),则需要为绘制的每个“grid”对象指定“default.units”参数。例如,如果您尝试在(2,4)处绘制点,您将永远不会看到该点,因为它将远离屏幕。指定default.units =“native”将会指出要使用视口自己的坐标系,并且会正确绘制点。

视口可以导航并直接写入,但除非您正在做一些非常自动化的操作,否则更容易指定视口,在其中绘制,然后“弹出”(完成)视口。这将返回到父视口,您可以从下一个视口开始。弹出每个视口是一个无杂乱的方法,将适合大多数目的(并使其更容易调试!)。

在绘制图形时,’dataViewport’功能非常重要。这是一种特殊类型的视口,可以处理所有的坐标和缩放,只要你告诉你你正在使用什么数据。这是我为任何绘图区域使用的。当我第一次开始使用’grid’包时,我调整了所有的值以适应“npc”坐标系,但这是一个错误!只要您记住为每个绘图项目使用“本机”单元,’dataViewport’功能就很容易。

放弃

数据可视化是我的强项,我不介意花半天的脚本编写好的视觉效果。 “网格”包允许我比我发现的任何事物更快地创建相当复杂的视觉效果。我将视觉设置为函数,因此我可以快速加载各种数据。我不开心

但是,如果你不喜欢脚本的话,“网格”将是你的敌人。另外,如果你认为半天的时间是一个视觉效果,那么“网格”不会帮你太多。 (in)着名的“ggplot2”包是大多数人定居的地方,我衷心地推荐它,尽管我个人觉得没有用处。

如果有人想要帮助学习“网格”图形,我更愿意帮助教学。它彻底改变了我创建快速,智能和好看的数据视觉的能力。

http://stackoverflow.com/questions/13081310/combining-multiple-complex-plots-as-panels-in-a-single-figure

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:将单个图形中的多个复杂图形组合为面板