使用 ggplot2 geom_tile() 突出显示由集群定义的图块组

Highlight groups of tiles defined by clusters using ggplot2 geom_tile()

我使用 ggplot2 检查数据集的某些聚类。如果我能够通过在它们周围画一个框或其他东西来突出属于同一集群的节点组,那就太好了。您将在下面找到一些示例代码,这些代码重现了我正在尝试做的事情,但真实数据一如既往地更加混乱。 :)

我四处寻找并找到了这个解决方案 here 来解决一个稍微不同的问题。理想情况下,在我的例子中,边界只会画在集群的外部。

set.seed(1916)
# what cluster do each user belong to?
cl_df = tibble(user = 1:100, cl = rep(1:3, c(20,30,50)))

df_example = 
  # create the grid
  expand.grid(user_1 = 1:100, user_2 = 1:100) %>% as_tibble %>%
  mutate(cl_1 = plyr::mapvalues(user_1, cl_df$user, cl_df$cl), 
         cl_2 = plyr::mapvalues(user_2, cl_df$user, cl_df$cl),
         same_cl = cl_1 == cl_2, 
         value = ifelse(same_cl, rnorm(sum(same_cl),1,1), rnorm(sum(!same_cl),2,1)))

df_example %>%
  ggplot(data = ., aes(x = reorder(user_1, cl_1),
                     y = reorder(user_2, cl_2), 
                     fill = value)) +
  geom_tile() + 
  scale_fill_gradientn(colours = terrain.colors(10)) +
  xlab('') + 
  ylab('') + 
  theme(axis.text.x=element_blank(),
        axis.ticks.x=element_blank(),
        axis.text.y=element_blank(),
        axis.ticks.y=element_blank())

在上面的例子中,沿着对角线有三个集群,我想在每个集群周围用一个框突出显示。

提前致谢(我即将进入可能只是我们 MS 绘画的阶段!)

graphics.off()
ggplot(data = df_example, aes(x = reorder(user_1, cl_1),
                 y = reorder(user_2, cl_2), 
                 fill = value)) +
    geom_tile() + 
    scale_fill_gradientn(colours = terrain.colors(10)) +
    xlab('') + 
    ylab('') + 
    theme(axis.text.x=element_blank(),
          axis.ticks.x=element_blank(),
          axis.text.y=element_blank(),
          axis.ticks.y=element_blank()) + 
geom_rect(mapping = aes(xmin = 1, xmax = 20, ymin = 1, ymax = 20),
          fill = NA, col = "black")  + 
geom_rect(mapping = aes(xmin = 20, xmax = 50, ymin = 20, ymax = 50),
          fill = NA, col = "black") +
geom_rect(mapping = aes(xmin = 50, xmax = 100, ymin = 50, ymax = 100),
          fill = NA, col = "black")

ggforce 中的 geom_mark_* 函数对此任务很有帮助。在这种情况下,我们可以指定每个 cl_1 组我们想要一个,我们只想突出显示 same_cl.

的数据
 ...
 ggforce::geom_mark_rect(aes(group = cl_1, filter = same_cl), 
                         expand = 0, radius = 0)