如何在 R 树形图中正确着色边缘或绘制矩形?
-
23-08-2019 - |
题
我生成了 这个树状图 使用 R 的 hclust()
, as.dendrogram()
和 plot.dendrogram()
功能。
我用的是 dendrapply()
函数和给叶子着色的局部函数,运行良好。
我的统计测试结果表明一组节点(例如 的簇“_+v\_stat5a\_01_
“ 和 ”_+v\_stat5b\_01_
”位于树的右下角)是重要的或重要的。
我还有一个可以使用的本地函数 dendrapply()
它在我的树状图中找到了包含重要叶子的确切节点。
我想要(按照示例):
- 为连接的边缘着色“
_+v\_stat5a\_01_
“ 和 ”_+v\_stat5b\_01_
”;或者, - 画一个
rect()
大约 ”_+v\_stat5a\_01_
“ 和 ”_+v\_stat5b\_01_
"
我有以下本地函数(“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_
" 会是红色的虚线。
我也尝试过使用 rect.hclust()
在此之内 if
堵塞:
ma <- match(leafList, orderedLabels)
rect.hclust(scoreClusterObj, h = a$height, x = c(min(ma), max(ma)), border = 2)
但结果不适用于水平树状图(IE。 带有水平标签的树状图)。 这是一个例子 (注意右下角的红色条纹)。关于什么的尺寸有些不正确 rect.hclust()
生成,我不知道它是如何工作的,以便能够编写我自己的版本。
我很感激任何建议 edgePar
或者 rect.hclust()
正常工作,或者能够编写我自己的 rect.hclust()
相等的。
更新
自从问这个问题以来,我用了 getAnywhere(rect.hclust())
获取计算参数并绘制的功能代码 rect
目的。我编写了该函数的自定义版本来处理水平和垂直叶子,并使用 dendrapply()
.
然而,有某种剪裁效果可以删除部分 rect
. 。对于水平叶子(绘制在树右侧的叶子),树的最右边缘 rect
要么消失,要么比其他三边的边框宽度薄 rect
. 。对于垂直叶子(绘制在树底部的叶子),树的最底边 rect
遇到同样的显示问题。
我所做的标记重要簇的方法是减少簇的宽度 rect
这样我就可以在簇边缘的尖端和(水平)叶子标签之间渲染垂直的红色条纹。
这消除了剪切问题,但引入了另一个问题,即簇边缘尖端和叶子标签之间的空间只有六个左右像素宽,我对此没有太多控制权。这限制了垂直条纹的宽度。
更糟糕的问题是 x
- 标记两个元素之间垂直条纹的位置的坐标将根据较大树的宽度而变化(par["usr"]
),这又取决于树层次结构最终的结构方式。
我写了一个“更正”,或者更好的说法,一个 hack 来调整这个 x
值和 rect
水平树的宽度。它并不总是一致地工作,但对于我正在制作的树,它似乎避免太接近(或重叠)边缘和标签。
最终,更好的解决办法是找出如何绘制 rect
这样就不会出现剪裁。或者用一致的方式来计算具体的 x
位于任何给定树的树边缘和标签之间,以便正确居中和调整条纹大小。
我也对用颜色或线条样式注释边缘的方法非常感兴趣。
解决方案
所以您实际上问了大约五个问题 (5 +/- 3)。至于编写您自己的 rect.hclust 之类的函数,来源位于 library/stats/R/identify.hclust.R
如果你想看的话。
我自己快速地看了一眼,不确定它是否达到了我在阅读你的描述时所认为的效果——它似乎在画画 多种的 矩形,此外, x
选择器似乎是硬编码的以水平分隔标签(这不是你想要的,而且没有 y
).
我会回来的,但与此同时,您可能(除了查看源代码之外)尝试使用不同的方法执行多个 rect.hclust border=
颜色和不同 h=
值来查看是否出现故障模式。
更新
我在这方面也没有太多运气。
剪切的一种可能的混乱是用尾随空格填充标签,然后稍微将矩形的边缘带入(其想法是,仅将矩形带入即可将其移出剪切区域,但会覆盖标签的末端)。
另一个想法是用半透明(低 Alpha)颜色填充矩形,形成阴影区域而不是边界框。