10

我正在使用 Dendextend 在 R 中绘制缠结。我想知道是否可以使用绘制多个子图par(mfrow = c(2,2))

我似乎无法弄清楚。

谢谢

library(dendextend)
dend15 <- c(1:5) %>% dist %>% hclust(method = "average") %>% as.dendrogram
dend15 <- dend15 %>% set("labels_to_char")
dend51 <- dend15 %>% set("labels", as.character(5:1)) %>% match_order_by_labels(dend15)
dends_15_51 <- dendlist(dend15, dend51)

par(mfrow = c(2,2))
tanglegram(dends_15_51)
tanglegram(dends_15_51)
tanglegram(dends_15_51)
tanglegram(dends_15_51)
4

2 回答 2

8

tl;dr:不能par(mfrow=...)与函数一起使用tanglegram,但可以使用layout

解释:如果你仔细看 function tanglegram,你会看到 ( methods(tanglegram)) ,在下面,有几个方法,其中,dendextend:::tanglegram.dendrogram调用它来绘制缠结图(可以在dendextend:::tanglegram.dendlistfunction 内部看到)。

在这个函数内部,有一个调用layout

layout(matrix(1:3, nrow = 1), widths = columns_width) 

这会“擦除”您之前的设置par(mfrow=c(2, 2))并将其更改为c(1, 3)(仅针对函数的“时间”,因为在函数结束时,值被重置......)。

确实,在 的帮助页面中layout,它说:

这些函数与在设备上安排绘图的其他机制完全不兼容:par(mfrow)、par(mfcol) 和 split.screen。

结论:如果你想在同一个“窗口”中绘制多个缠结图,你需要在layout调用之前使用调用(有 12 个子部分:2 行和 6 列)并使用参数tanglegram抑制layout内部调用。tanglegramjust_one=FALSE

绘制多个缠结图的示例:

使用下面的代码,您可以获得所需的绘图(我将函数的默认宽度用于布局):

layout(matrix(1:12, nrow=2, byrow=TRUE), widths=rep(c(5, 3, 5), 2))
tanglegram.dendlist_mod(dends_15_51, just_one=FALSE)
tanglegram.dendlist_mod(dends_15_51, just_one=FALSE)
tanglegram.dendlist_mod(dends_15_51, just_one=FALSE)
tanglegram.dendlist_mod(dends_15_51, just_one=FALSE)

在此处输入图像描述

这是通过更新 dendextend 包完成的,其中: 我修改了 2 个函数tanglegram.dendrogramtanglegram.dendlist添加了一个just_one参数,该参数默认为TRUE并将layoutin的行更改tanglegram.dendrogram为:

 if (just_one) layout(matrix(1:3, nrow = 1), widths = columns_width)

我还抑制了par参数的重置,当然还更改了调用tanglegram.dendlist(现在称为tanglegram.dendlist_mod),因此它调用了新的修改函数,合并了just_one参数并将其传递给修改后的tanglegram.dendrogram函数。

于 2016-10-04T10:00:06.333 回答
4

您可以创建多个图并在将它们放入文档时排列它们,而不是在单个图形设备中创建组合图。该knitr软件包使执行此操作变得容易,方法是使用fig.show = "hold"在单个 R 块中生成的多个图并指定相关的out.width,例如 50% 以连续两个图,当图放置在文档中时。

例如,在 R markdown ( .Rmd) 文件中,您可能有

```{r, fig.show = "hold", out.width = "50%", echo = FALSE}
suppressPackageStartupMessages(library(dendextend))
dend15 <- c(1:5) %>% dist %>% hclust(method = "average") %>% as.dendrogram
dend15 <- dend15 %>% set("labels_to_char")
dend51 <- dend15 %>% set("labels", as.character(5:1)) %>% match_order_by_labels(dend15)
dends_15_51 <- dendlist(dend15, dend51)
tanglegram(dends_15_51, margin_outer = 1)
plot.new()
tanglegram(dends_15_51, margin_outer = 1)
plot.new()
tanglegram(dends_15_51, margin_outer = 1)
plot.new()
tanglegram(dends_15_51, margin_outer = 1)
```

将其knit转换为 HTML 时,将如下所示:

在此处输入图像描述

我对代码做了一些修改:

  • 禁止来自dendextend.
  • 增加默认值margin_outer以避免与相邻图重叠的 x 轴标签。
  • plot.new()在对 的调用之间添加tanglegram,否则下一个图将绘制在前一个图之上(这是使用的结果,tanglegram通常layout在生成多个图时不需要)。

.Rnw在文件中可以使用相同的方法。如果您正在编译为 PDF(通过 LaTeX),您可以添加图形标题和子标题,请参阅knitr演示 #067 - 图形选项了解更多详细信息。

于 2016-10-04T13:24:47.110 回答