gpt4 book ai didi

r - 将多个复杂图作为面板组合在一个图中

转载 作者:行者123 更新时间:2023-12-03 12:10:23 25 4
gpt4 key购买 nike

@backlin的介绍

可以使用layoutpar(mfrow=...)将多个简单图作为面板组合成一个图形。但是,更复杂的图倾向于在内部设置其自己的面板布局,从而使其无法用作面板。有没有一种方法可以创建嵌套的布局并将复杂的图封装到单个面板中?

我觉得grid包可以完成此操作,例如通过将面板绘制在单独的视口(viewport)中,但还无法弄清楚该怎么做。这是一个玩具示例说明此问题:

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的原始问题

我使用 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 ),
)

但是,由于我想在一个图中比较多个热图,因此我使用 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所建议的)原始使用'grid'软件包。许多预构建的图形包会覆盖所有当前视口(viewport)并绘制设备设置,因此,如果您想以一种非常特定的方式完成某件事,则必须自己构建它。

我建议拿起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()定义绘图窗口的属性,“网格”称为“视口(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")))这里有一些需要注意的地方...请参阅视口(viewport)的更详细说明。
  • pushViewport()这用于初始化veiwport。您可以将其包装在视口(viewport)定义周围,以实际执行视口(viewport),如下所示:pushViewport(dataViewport([stuff in here]))
  • popViewport()这将完成一个视口(viewport),并使您在视口(viewport)层次结构中上移一层。请参阅视口(viewport)的更详细说明。

  • 视口(viewport)简而言之

    视口(viewport)是临时绘制空间,用于定义在何处以及如何绘制“网格”对象。视口(viewport)内部的所有内容都是相对于视口(viewport)绘制的。如果旋转视口(viewport),则内部的所有内容都会旋转。视口(viewport)可以嵌套,可以重叠并且几乎无限灵活,但有一个异常(exception):它们始终是矩形。

    最初使很多人困惑的是坐标系。每个视口(viewport),包括初始的“grid.newpage()”视口(viewport),在x轴和y轴上都从0变为1。原点(0,0)是最左下角,最大值(1,1)是最右上角。这是“npc”单位制,所有没有指定单位的东西都可能最终会根据此系统绘制。这对您意味着两件事:
  • 指定视口(viewport)大小和位置时,请使用“npc”系统。只需假设您的视口(viewport)必须使用“npc”坐标,您就可以节省很多麻烦。这意味着如果我要彼此相邻绘制两个图,则两个视口(viewport)的定义将类似于:
  • 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"))
  • 如果您的视口(viewport)具有不同的坐标系(例如,用于绘制图形的视口(viewport)),则需要为绘制的每个“网格”对象指定“default.units”参数。例如,如果您试图在(2,4)处绘制一个点,那么您将永远看不到该点,因为它离屏幕很远。指定default.units="native"将指示该点使用视口(viewport)自己的坐标系,并正确绘制该点。

  • 视口(viewport)可以直接导航和写入,但是除非您执行非常自动化的操作,否则指定视口(viewport),在视口(viewport)内绘制然后“ pop ”(完成)视口(viewport)会更加容易。这将使您返回到父视口(viewport),并且您可以从下一个视口(viewport)开始。 pop 每个视口(viewport)是一种无杂乱的方法,将适合大多数目的(并使调试更容易!)。

    绘制图形时,“dataViewport”功能非常重要。这是一种特殊的视口(viewport),只要您告诉它所使用的数据,即可为您处理所有坐标和比例。这是我用于任何绘图区域的图形。刚开始使用“grid”软件包时,我调整了所有值以适合“npc”坐标系,但这是一个错误!只要您记得为每个绘图项目使用“本机”单位,“dataViewport”功能就可以轻松实现。

    免责声明

    数据可视化是我的强项,我不介意花半天的时间编写好视觉效果的脚本。 “网格”程序包使我可以比发现的任何其他东西更快地创建非常复杂的视觉效果。我将视觉效果编写为函数,因此可以快速加载各种数据。我再开心不过了。

    但是,如果您不喜欢编写脚本,那么“网格”将是您的敌人。另外,如果您认为半天的时间对于视觉效果来说太长了,那么“网格”对您的帮助就不会太多。众所周知的“ggplot2”软件包是大多数人都喜欢的软件包,尽管我个人认为它没有用,但我还是由衷地推荐它。

    如果有人想要帮助学习“网格”图形,我非常乐于帮助教书。它彻底改变了我创建快速,智能和美观数据可视化效果的能力。

    关于r - 将多个复杂图作为面板组合在一个图中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13081310/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com