将 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))
在每个方面,我有:
- 面 0:
w==0L
的 X、Y、Z,w==0L
的轮廓
- 面 1:
w==1L
的 X、Y、Z,w==1L
的轮廓
- 面 2:
w==2L
的 X、Y、Z,w==2L
的轮廓
我想要的是一个有效的窗格:
w==0L
的 X、Y、Z,w
分类 的所有值的轮廓
(请原谅我仓促的 GIMP 技巧。在实际数据中,轮廓可能不会重叠,但我认为这不会成为问题。)
对于相同的 X,Y 系统,真实数据具有 z
的不同值(和梯度),因此轮廓在其他方面与第一个面兼容。但是,它仍然是 "different",所以我不能用单个 w==0L
数据模拟轮廓。
我想可能有几种方法可以做到这一点:
- 第一次形成数据"right",通知
ggplot
如何拉出等高线并将它们放在单个图上(例如,对某些层使用不同的data=
);
- 形成分面图,从其他分面提取轮廓,将它们应用于第一个分面,并丢弃其他分面(可能使用
grid
and/or gtable
);或者也许
- (自己用数学方法计算轮廓并将它们添加为独立的线;我希望重新使用
ggplot2
的努力来避免这种情况...)。
它不太适合图形语法,但您可以为每个数据子集添加一个 geom_contour
调用。一种快速的方法是将此类调用的列表添加到图形中,您可以通过 lapply
ing 跨拆分数据快速生成它:
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))
})
我有 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))
在每个方面,我有:
- 面 0:
w==0L
的 X、Y、Z,w==0L
的轮廓
- 面 1:
w==1L
的 X、Y、Z,w==1L
的轮廓
- 面 2:
w==2L
的 X、Y、Z,w==2L
的轮廓
我想要的是一个有效的窗格:
w==0L
的 X、Y、Z,w
分类 的所有值的轮廓
(请原谅我仓促的 GIMP 技巧。在实际数据中,轮廓可能不会重叠,但我认为这不会成为问题。)
对于相同的 X,Y 系统,真实数据具有 z
的不同值(和梯度),因此轮廓在其他方面与第一个面兼容。但是,它仍然是 "different",所以我不能用单个 w==0L
数据模拟轮廓。
我想可能有几种方法可以做到这一点:
- 第一次形成数据"right",通知
ggplot
如何拉出等高线并将它们放在单个图上(例如,对某些层使用不同的data=
); - 形成分面图,从其他分面提取轮廓,将它们应用于第一个分面,并丢弃其他分面(可能使用
grid
and/orgtable
);或者也许 - (自己用数学方法计算轮廓并将它们添加为独立的线;我希望重新使用
ggplot2
的努力来避免这种情况...)。
它不太适合图形语法,但您可以为每个数据子集添加一个 geom_contour
调用。一种快速的方法是将此类调用的列表添加到图形中,您可以通过 lapply
ing 跨拆分数据快速生成它:
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))
})