使用 dendextend 在 R 中绘制 tanglegrams 子图

Plotting tanglegrams subplots in R using dendextend

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

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

解释: 如果你仔细观察函数 tanglegram,你会发现 (methods(tanglegram)) 下面有几个方法,其中其中,dendextend:::tanglegram.dendrogram 被调用来绘制 tanglegram(在 dendextend:::tanglegram.dendlist 函数中可以看到)。

在这个函数里面,调用了layout:

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

这个 "erases" 您之前设置的 par(mfrow=c(2, 2)) 并将其更改为 c(1, 3) (只是为了函数的 "time" 因为在函数的末尾,该值已重置...)。

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

These functions are totally incompatible with the other mechanisms for arranging plots on a device: par(mfrow), par(mfcol) and split.screen.

结论: 如果你想在同一个 "window" 中绘制多个缠结图,你需要使用 layout 调用(有 12 个子部分: 2 行和 6 列)在调用 tanglegram 之前使用参数 just_one=FALSE.

抑制 tanglegram 内的 layout 调用

绘制多个缠结图的示例:

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

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并将 tanglegram.dendrogram 中的 layout 行更改为:

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

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

您可以创建多个图并在将它们放入文档时排列它们,而不是在单个图形设备中创建组合图。 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 轴标签重叠。
  • tanglegram 的调用之间添加了 plot.new(),否则下一个图将绘制在前一个图的顶部(这是 tanglegram 使用 layout 并且在生成多个图时通常不需要)。

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