2016-09-30 189 views
10

我正在使用dendextend来绘制R中的Tanglegrams。我想知道是否可以使用par(mfrow = c(2,2))绘制多个子图?使用dendextend在R中绘制纠结图子图

我似乎无法弄清楚。

感谢

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) 

回答

7

TL;博士:这是不可能使用par(mfrow=...)与功能tanglegram,但它使用layout是可能的。

说明:如果你看一下功能tanglegram近,你会看到(methods(tanglegram)),在骨子里,有几种方法,其中,dendextend:::tanglegram.dendrogram这就是所谓绘制tanglegram(如可以在里面dendextend:::tanglegram.dendlist可见功能)。

在这个函数中,有一个layout呼叫:

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

这种“擦除”你以前的par(mfrow=c(2, 2))设置,并在其更改为c(1, 3)(只为功能的“时间”,但因为函数结束时,值被重置...)。

事实上,在layout帮助页面,它说:

这些功能与其他机制安排的设备上图完全不相容:PAR(mfrow),标准杆(mfcol)和分裂。屏幕。

结论:如果你想在同一个“窗口”,以绘制几个tanglegrams你需要使用layout通话(与12子部分:2行6列)提前调用到tanglegram和使用参数just_one=FALSE来抑制layout内部tanglegram的呼叫。

绘制几个tanglegrams的例子:

使用下面的代码,就可以得到所希望的描绘(我把函数的默认宽度为布局):

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) 

enter image description here

这是通过更新dendextend包完成的,其中:我修改了2个函数tanglegram.dendrogramtanglegram.dendlist添加just_one参数,默认为TRUE并改变了layout的线在tanglegram.dendrogram到:

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

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

+2

作为一个快速的替代方法,你可以抓住图像,并将其转换为网格对象,然后结合在一起。http://stackoverflow.com/questions/27929452/r-return-corrplot-as-object/#27948707 – user20650

+1

@ user20650我想过使用'grid',但没有意识到可以抓取图像。我一直想念这个包,谢谢! – Cath

+1

@ user20650不错的主意,但不幸的是,您链接到的解决方案不适用于tanglegram。问题似乎是水平树形图上的“grid.echo”扼流圈(例如,'图(dend51); grid.echo()'工作,'plot(dend51,horiz = TRUE); grid.echo()会抛出一个错误),这是将图像转换为网格对象所必需的。 –

4

不是在单个图形设备中创建组合图,而是将它们放入文档中时创建多个图并进行排列。 knitr包通过使用fig.show = "hold"来保持在单个R块中产生的多个图并且指定相关的out.width(例如, 50%有连续两个地块,因为当地块放置在文件中时。

例如,在R降价(.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,看起来像下面这样:

enter image description here

有几个我对代码所做的修改:

  • dendextend中取消软件包启动消息。
  • 增加了默认值margin_outer以避免重叠来自邻近图的x轴标签。
  • 在调用tanglegram之间添加了plot.new(),否则下一个图将绘制在前一个图上(这是tanglegram使用layout的结果,并且在生成多个图时通常不需要)。

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