如何在热图中围绕 "groups" 画框?

How to draw boxes around "groups" in a heatmap?

我画了这样一张图:

library(reshape2)
library(ggplot2)

m <- matrix(1:64 - 32, 8)
rownames(m) <- colnames(m) <-
  c(paste0("a", 1:3), paste0("b", 1:2), paste0("c", 1:3))
d <- melt(m)
gg <- ggplot(d) +
  geom_tile(aes(x = Var1, y = Var2, fill = value)) +
  scale_fill_gradient2()

如何以编程方式围绕 "a"、"b" 和 "c" 组绘制框?

矩阵m总是方阵。 colnames(m)rownames(m) 将始终相同。因此,方框将覆盖整个网格并且永远不会重叠。一般来说,团体人数会有所不同。

我也没有和 ggplot2 结婚。如果它不比 ggplot2/grid 版本更挑剔,我愿意使用 image 的基础图形解决方案。

我做到了

d$group <- substr(d$Var1, 1, 1)

在我意识到我不知道如何继续之前。


我有:

我想要的:

即像这样:

xmin <- c(0.5,3.5,5.5)
xmax <- c(3.5,5.5,8.5)
ymin <- c(0.5,3.5,5.5)
ymax <- c(3.5,5.5,8.5)
box1 <- data.frame(xmin = rep(xmin,times = 3),
                   xmax = rep(xmax,each = 3),
                   ymin = rep(ymin,times = 3),
                   ymax = rep(ymax,each = 3))
ggplot(melt(m)) +
    geom_tile(aes(x = Var1, y = Var2, fill = value)) +
    geom_rect(data = box1,aes(xmin = xmin,xmax = xmax,ymin = ymin,ymax= ymax),
                        fill = NA,color = "black") +
    scale_fill_gradient2()

另一种选择是简单地使用 geom_hlinegeom_vline,尽管您可能很难去除超出彩色矩形边缘的小部分。

geom_segment

library('reshape2')
library('ggplot2')

m <- matrix(1:64 - 32, 8)
rownames(m) <- colnames(m) <-
  c(paste0("a", 1:3), paste0("b", 1:2), paste0("c", 1:3))
gg <- ggplot(melt(m)) +
  geom_tile(aes(x = Var1, y = Var2, fill = value)) +
  scale_fill_gradient2()

tt <- table(gsub('\d+', '', colnames(m)))
ll <- unname(c(0, cumsum(tt)) + .5)

gg + geom_segment(aes(x = ll, xend = ll, y = head(ll, 1), yend = tail(ll, 1))) + 
  geom_segment(aes(y = ll, yend = ll, x = head(ll, 1), xend = tail(ll, 1)))

这可能被认为是作弊,但很容易:

# Depending on your data you may be able to generate `d2` directly
# here we need to re-order a bit

d2 <- transform(
   d, V1 = substr(Var1, 1, 1), 
   V2=factor(substr(Var2, 1, 1), levels=letters[3:1])
)
ggplot(d2) +
  geom_tile(aes(x = Var1, y = Var2, fill = value)) +
  scale_fill_gradient2() +
  facet_grid(V2 ~ V1, scales="free", space="free")