I have x,y,z data with categorical variables that facilitate a facet. I want to include contour lines from all but the first facet and discard the rest of the data. One way to visualize the process is to facet the data and mentally move the contours from the other facets to the first.
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))
In each facet, I have:
w==0L
, contour for w==0L
w==1L
, contour for w==1L
w==2L
, contour for w==2L
What I'd like to have is a single pane, effectively:
w==0L
, contour for all values of the w
categorical(Forgive my hasty GIMP skills. In the real data, the contours will likely not overlap, but I don't think that that would be a problem.)
The real data has different values (and gradients) of z
for the same X,Y system, so the contour is otherwise compatible with the first facet. However, it's still "different", so I cannot mock-up the contours with the single w==0L
data.
I imagine there might be a few ways to do this:
ggplot
how to pull the contours but lay them on the single plot (e.g., using different data=
for certain layers);grid
and/or gtable
); or perhapsggplot2
's efforts to avoid this ...).It doesn't fit so neatly with the grammar of graphics, but you can just add a geom_contour
call for each subset of data. A quick way is to add a list of such calls to the graph, which you can generate quickly by lapply
ing across the split data:
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))
})
You can even make a legend, if you need:
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))
})