如何在 R 树状图中正确着色边缘或绘制矩形?

Posted

技术标签:

【中文标题】如何在 R 树状图中正确着色边缘或绘制矩形?【英文标题】:How do I color edges or draw rects correctly in an R dendrogram? 【发布时间】:2010-10-17 14:15:18 【问题描述】:

我使用 R 的 hclust()as.dendrogram()plot.dendrogram() 函数生成了 this dendrogram。

我使用了dendrapply() 函数和一个局部函数来给树叶上色,效果很好。

我有一个统计测试的结果表明一组节点(例如树右下角的“_+v\_stat5a\_01_”和“_+v\_stat5b\_01_”集群)是重要的或重要的。

我还有一个可以与dendrapply() 一起使用的本地函数,它可以在我的树状图中找到包含重要叶子的确切节点。

我愿意(按照示例):

    为连接“_+v\_stat5a\_01_”和“_+v\_stat5b\_01_”的边缘着色;或者, 在“_+v\_stat5a\_01_”和“_+v\_stat5b\_01_”周围画一个rect()

我有以下本地函数(“nodes-in-leafList-match-nodes-in-clusterList”条件的细节并不重要,但它突出了重要的节点):

markSignificantClusters <<- function (n) 
  if (!is.leaf(n)) 
     a <- attributes(n)
     leafList <- unlist(dendrapply(n, listLabels))
     for (clusterIndex in 1:length(significantClustersList[[1]])) 
       clusterList <- unlist(significantClustersList[[1]][clusterIndex])
       if (nodes-in-leafList-match-nodes-in-clusterList) 
          # I now have a node "n" that contains significant leaves, and
          # I'd like to use a dendrapply() call to another local function
          # which colors the edges that run down to the leaves; or, draw
          # a rect() around the leaves
       
     
  

在这个if 块中,我尝试调用dendrapply(n, markEdges),但这不起作用:

markEdges <<- function (n) 
  a <- attributes(n)
  attr(n, "edgePar") <- c(a$edgePar, list(lty=3, col="red"))

在我的理想示例中,连接“_+v\_stat5a\_01_”和“_+v\_stat5b\_01_”的边将是红色的虚线。

我也尝试在这个if 块中使用rect.hclust()

ma <- match(leafList, orderedLabels)  
rect.hclust(scoreClusterObj, h = a$height, x = c(min(ma), max(ma)), border = 2)

但结果不适用于水平树状图(带有水平标签的树状图)。 Here is an example(注意右下角的红色条纹)。 rect.hclust() 生成的内容的尺寸不正确,我不知道它是如何工作的,以便能够编写自己的版本。

感谢任何关于让 edgeParrect.hclust() 正常工作或能够编写自己的 rect.hclust() 等效项的建议。

更新

自从问了这个问题,我就用getAnywhere(rect.hclust())得到了计算参数和绘制rect对象的功能代码。我写了这个函数的自定义版本来处理水平和垂直叶子,并用dendrapply()调用它。

但是,有某种剪裁效果会删除rect 的一部分。对于水平叶子(在树右侧绘制的叶子),rect 的最右侧边缘要么消失,要么比rect 的其他三个边的边框宽度更窄。对于垂直叶子(在树底部绘制的叶子),rect 的最底部边缘会遇到相同的显示问题。

作为标记重要集群的一种方法,我所做的是减小rect 的宽度,以便在集群边缘的尖端和(水平)叶子标签之间呈现一条垂直的红色条纹。

这消除了裁剪问题,但引入了另一个问题,即簇边缘尖端和叶子标签之间的空间只有六个左右像素宽,我对此没有太多控制权。这限制了垂直条纹的宽度。

更糟糕的问题是x-坐标标记垂直条纹可以适合两个元素之间的位置将根据较大树的宽度(par["usr"])而变化,这又取决于树如何层次结构最终被结构化。

我写了一个“更正”,或者更好的说法,一个 hack 来调整这个 x 值和水平树的 rect 宽度。它并不总是始终如一地工作,但对于我正在制作的树木,它似乎不会太靠近(或重叠)边缘和标签。

最终,更好的解决方法是找出如何绘制rect,这样就不会出现剪辑。或者一种一致的方法来计算任何给定树的树边缘和标签之间的特定x 位置,以便正确地居中和调整条带的大小。

我也对用颜色或线条样式注释边缘的方法非常感兴趣。

【问题讨论】:

嗯,我在dendextend包中写了一个rect.dendrogram函数。还有一个基于它们包含的标签为分支着色的功能,称为branches_attr_by_labels 【参考方案1】:

所以您实际上已经问了五个问题 (5 +/- 3)。至于编写自己的类似 rect.hclust 的函数,如果你想看的话,源代码在library/stats/R/identify.hclust.R

我自己快速浏览了一下,并不确定它是否符合我阅读您的描述时的想法 - 它似乎正在绘制 多个 矩形,另外,x 选择器似乎是硬编码来水平隔离标签(这不是你想要的,也没有y)。

我会回来的,但与此同时,您可能(除了查看源代码之外)尝试使用不同的border= 颜色和不同的h= 值执行多个 rect.hclust,以查看是否出现故障模式。

更新

我在这方面也没有太多运气。

剪辑的一​​个可能的问题是用尾随空格填充标签,然后稍微将矩形的边缘带入(想法是仅将矩形带入将使其脱离剪辑区域但覆盖末端标签)。

另一个想法是用半透明(低 alpha)颜色填充矩形,形成阴影区域而不是边界框。

【讨论】:

以上是关于如何在 R 树状图中正确着色边缘或绘制矩形?的主要内容,如果未能解决你的问题,请参考以下文章

如何在分层热图树状图中添加聚类矩形

如何使用 R 为多路复用网络中的边缘着色

Opengl 未使用着色器正确绘制 - 矩阵设置/初始化问题?

如何在着色器之后读取像素?

R语言层次聚类(hierarchical clustering):使用scale函数进行特征缩放hclust包层次聚类(创建距离矩阵聚类绘制树状图dendrogram,在树状图上绘制红色矩形框)

如何使用 R 根据子项的标签标记树状图中的每个节点