Change Dendrogram leaves
我想修改从 hclust 对象的绘图生成的树状图中叶子的属性。最低限度,我想更改颜色,但您可以提供的任何帮助将不胜感激。
我确实尝试用谷歌搜索答案,但我看到的每一个解决方案似乎都比我想象的要困难得多。
不久前,Joris Meys 好心地向我提供了这段改变树叶颜色的代码片段。修改它以反映您的属性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | clusDendro <- as.dendrogram(Clustering) labelColors <- c("red","blue","darkgreen","darkgrey","purple") ## function to get colorlabels colLab <- function(n) { if(is.leaf(n)) { a <- attributes(n) # clusMember - a vector designating leaf grouping # labelColors - a vector of colors for the above grouping labCol <- labelColors[clusMember[which(names(clusMember) == a$label)]] attr(n,"nodePar") <- c(a$nodePar, lab.col = labCol) } n } ## Graph clusDendro <- dendrapply(clusDendro, colLab) op <- par(mar = par("mar") + c(0,0,0,2)) plot(clusDendro, main ="Major title", horiz = T, type ="triangle", center = T) par(op) |
这里有一个解决这个问题的方法,它使用了一个名为 "dendextend" 的新包,专为这类事情而构建。
您可以在以下 URL 的"使用"部分的演示文稿和小插图中看到许多示例:https://github.com/talgalili/dendextend
这是这个问题的解决方案:
1 2 3 4 5 6 7 8 | # define dendrogram object to play with: dend <- as.dendrogram(hclust(dist(USArrests[1:3,]),"ave")) # loading the package install.packages('dendextend') # it is now on CRAN library(dendextend)# let's add some color: labels_colors(dend) <- 2:4 labels_colors(dend) plot(dend) |
不清楚你想用它做什么,但我经常需要在树状图中识别一个分支。我已经破解了 rect.hclust 方法来添加密度和标签输入。
你可以这样称呼它:
1 2 3 4 | k <- 3 # number of branches to identify labels.to.identify <- c('1','2','3') required.density <- 10 # the density of shading lines, in lines per inch rect.hclust.nice(tree, k, labels=labels.to.identify, density=density.required) |
这里是函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | rect.hclust.nice = function (tree, k = NULL, which = NULL, x = NULL, h = NULL, border = 2, cluster = NULL, density = NULL,labels = NULL, ...) { if (length(h) > 1 | length(k) > 1) stop("'k' and 'h' must be a scalar") if (!is.null(h)) { if (!is.null(k)) stop("specify exactly one of 'k' and 'h'") k <- min(which(rev(tree$height) < h)) k <- max(k, 2) } else if (is.null(k)) stop("specify exactly one of 'k' and 'h'") if (k < 2 | k > length(tree$height)) stop(gettextf("k must be between 2 and %d", length(tree$height)), domain = NA) if (is.null(cluster)) cluster <- cutree(tree, k = k) clustab <- table(cluster)[unique(cluster[tree$order])] m <- c(0, cumsum(clustab)) if (!is.null(x)) { if (!is.null(which)) stop("specify exactly one of 'which' and 'x'") which <- x for (n in 1L:length(x)) which[n] <- max(which(m < x[n])) } else if (is.null(which)) which <- 1L:k if (any(which > k)) stop(gettextf("all elements of 'which' must be between 1 and %d", k), domain = NA) border <- rep(border, length.out = length(which)) labels <- rep(labels, length.out = length(which)) retval <- list() for (n in 1L:length(which)) { rect(m[which[n]] + 0.66, par("usr")[3L], m[which[n] + 1] + 0.33, mean(rev(tree$height)[(k - 1):k]), border = border[n], col = border[n], density = density, ...) text((m[which[n]] + m[which[n] + 1]+1)/2, grconvertY(grconvertY(par("usr")[3L],"user","ndc")+0.02,"ndc","user"),labels[n]) retval[[n]] <- which(cluster == as.integer(names(clustab)[which[n]])) } invisible(retval) } |