geom_tile:清除对角线瓦片边框

5

我用geom_tile创建了一个热图,其中x和y的值相同且按相同的方式排序。 我希望在图表对角线上的瓷砖周围添加黑色边框。

set.seed(42L)
data <- data.frame(x = rep(letters[1:3], each = 3L), 
                   y = rep(letters[1:3], 3L), 
                   fill = rnorm(9L))

我的建议是使用color aes,并将变量设置为TRUENA,然后使用scale_color_manual来删除NA值的灰色边框。

data$diag <- data$x == data$y
data$diag[!data$diag] <- NA

ggplot(data, aes(x = x, y = y, fill = fill)) +
  geom_tile(aes(color = diag), size = 2) +
  scale_color_manual(guide = FALSE, values = c(`TRUE` = "black"))

enter image description here

但是渲染效果不是很清晰,边框看起来有点被“隐形”的NA边框覆盖了。

如何改进我的图表?还有其他方法吗? 谢谢。

2个回答

7
似乎边框不是由"无形"的NA边框覆盖,因为它们实际上不存在,而是由瓦片本身覆盖。这意味着我们在处理层次顺序。那么我们可以尝试先添加一个纯粹的geom_tile,然后再添加另一个geom_tile,只使用对角线瓦片的数据来添加边框。也就是说,
ggplot(data, aes(x = x, y = y, fill = fill)) + geom_tile() +
  geom_tile(data = data[!is.na(data$diag), ], aes(color = diag), size = 2) +
  scale_color_manual(guide = FALSE, values = c(`TRUE` = "black"))

enter image description here

你的问题涉及到另一个,在那里所有的瓷砖都有边框,目标是让它们不重叠。然后可以调整瓷砖大小以创建边框空间。但在这种情况下,通过调整瓷砖大小,我们会创建一些缝隙,这使得事情看起来更糟。
ggplot(data, aes(x = x, y = y, fill = fill)) +
  geom_tile(aes(color = diag), width = 0.98, height = 0.98, size = 2) +
  scale_color_manual(guide = FALSE, values = c(`TRUE` = "black"))

enter image description here

另一方面,它支持这样的想法:在同一个geom_tile调用中无法调整图层的顺序。
最后,还有另一种灵感来自@utubun的答案的替代方法。
data$diag <- data$x == data$y
ggplot(data[order(data$diag), ], aes(x = x, y = y, fill = fill)) +
  geom_tile(aes(color = diag), size = 2) +
  scale_color_manual(guide = FALSE, values = c(`TRUE` = "black", `FALSE` = NA))

在这种情况下,我们在调用内部对数据进行排序,但还需要指定边框为FALSE,使其不可见。

确实,如果它被瓷砖本身覆盖,那就更有意义了,谢谢。在同一个geom_tile函数中没有办法做到这一点吗? - Julien Navarre
@JulienNavarre,我不这么认为,我在那里添加了一些注释。 - Julius Vainora
@JulienNavarre,utubun的回答更深入地解释了这个重叠问题:不仅是边框上的瓷砖,而且后面的行也会覆盖前面的行,因此预先对行进行排序也提供了一种解决方案。当然,除了额外的geom_tile之外,还必须对数据进行排序。 - Julius Vainora

6

通过改变原始数据框的排序(确保最后绘制边界瓷砖),无需再次调用geom_tile()即可达到所需结果:

set.seed(42L)

dat <- data.frame(
    x    = rep(letters[1:3], each  = 3L), 
    y    = rep(letters[1:3], times = 3L), 
    fill = rnorm(9L)
  ) |>
  dplyr::mutate(isdiag = (x == y)) |>
  dplyr::arrange(isdiag)

  ggplot(dat, aes(x = x, y = y, fill = fill)) +
      geom_tile(size = 2, colour = dat$isdiag) +
      theme_bw() +
      theme(axis.title = element_blank())

tiles


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接