将 ggplot2 轮廓从其他方面移动到主要方面

move ggplot2 contour from other facets to main

我有 x、y、z 数据,其中包含有助于分面的分类变量。我想包括除第一个面之外的所有轮廓线,并丢弃其余数据。可视化该过程的一种方法是对数据进行分面,并在脑海中将轮廓从其他方面移动到第一个方面。

MWE:

library(ggplot2)
library(dplyr)

data(volcano)
nx <- 87; ny <- 61
vdat <- data_frame(w=0L, x=rep(seq_len(nx), ny), y=rep(seq_len(ny), each=nx), z=c(volcano))
vdat <- bind_rows(vdat,
                  mutate(vdat, w=1L, x=x+4, y=y+4, z=z-20),
                  mutate(vdat, w=2L, x=x+8, y=y+8, z=z-40))

ggplot(vdat, aes(x, y, fill=z)) +
  geom_tile() +
  facet_wrap(~ w, nrow=1) +
  geom_contour(aes(z=z), color='white', breaks=c(-Inf,110,Inf))

在每个方面,我有:

我想要的是一个有效的窗格:

(请原谅我仓促的 GIMP 技巧。在实际数据中,轮廓可能不会重叠,但我认为这不会成为问题。)

对于相同的 X,Y 系统,真实数据具有 z 的不同值(和梯度),因此轮廓在其他方面与第一个面兼容。但是,它仍然是 "different",所以我不能用单个 w==0L 数据模拟轮廓。

我想可能有几种方法可以做到这一点:

它不太适合图形语法,但您可以为每个数据子集添加一个 geom_contour 调用。一种快速的方法是将此类调用的列表添加到图形中,您可以通过 lapplying 跨拆分数据快速生成它:

ggplot(vdat[vdat$w == 0, ], aes(x, y, z = z, fill = z)) +
    geom_tile() +
    lapply(split(vdat, vdat$w), function(dat){
        geom_contour(data = dat, color = 'white', breaks = c(-Inf, 110, Inf))
    })

如果需要,您甚至可以制作图例:

ggplot(vdat[vdat$w == 0, ], aes(x, y, z = z, fill = z, color = factor(w))) +
    geom_raster() +
    lapply(split(vdat, vdat$w), function(dat){
        geom_contour(data = dat, breaks = c(-Inf, 110, Inf))
    })