ggplot, рисование нескольких линий по граням
Я нарисовал две панели в столбце с помощью фасета ggplot2 и хотел бы добавить две вертикальные линии через панели при x = 4 и 8. Следующий код:
library(ggplot2)
library(gtable)
library(grid)
dat <- data.frame(x=rep(1:10,2),y=1:20+rnorm(20),z=c(rep("A",10),rep("B",10)))
P <- ggplot(dat,aes(x,y)) + geom_point() + facet_grid(z~.) + xlim(0,10)
Pb <- ggplot_build(P);Pg <- ggplot_gtable(Pb)
for (i in c(4,8)){
Pg <- gtable_add_grob(Pg, moveToGrob(i/10,0),t=8,l=4)
Pg <- gtable_add_grob(Pg, lineToGrob(i/10,1),t=6,l=4)
}
Pg$layout$clip <- "off"
grid.newpage()
grid.draw(Pg)
вышеуказанный код изменен от:ggplot, проводя линию между точками по граням.
И .
на этом рисунке есть две проблемы. Сначала была показана только одна вертикальная линия. Кажется, что moveToGrob
только один раз работал.. Во-вторых, показанная линия не является точной при x = 4. Я не найдите Pb$panel$ranges
переменная, так есть ли способ, которым я могу исправить диапазон? Большое спасибо.
2 ответов
обновлено до ggplot2 V3.0.0
в простом сценарии, где панели имеют общие оси, а линии простираются через весь диапазон y, вы можете рисовать линии по всем ячейкам gtable, найдя правильное преобразование координат npc (cf предыдущий пост, обновленный, потому что ggplot2 продолжает меняться),
library(ggplot2)
library(gtable)
library(grid)
dat <- data.frame(x=rep(1:10,2),y=1:20+rnorm(20),z=c(rep("A",10),rep("B",10)))
p <- ggplot(dat,aes(x,y)) + geom_point() + facet_grid(z~.) + xlim(0,10)
pb <- ggplot_build(p)
pg <- ggplot_gtable(pb)
data2npc <- function(x, panel = 1L, axis = "x") {
range <- pb$layout$panel_params[[panel]][[paste0(axis,".range")]]
scales::rescale(c(range, x), c(0,1))[-c(1,2)]
}
start <- sapply(c(4,8), data2npc, panel=1, axis="x")
pg <- gtable_add_grob(pg, segmentsGrob(x0=start, x1=start, y0=0, y1=1, gp=gpar(lty=2)), t=7, b=9, l=5)
grid.newpage()
grid.draw(pg)
вы можете просто использовать geom_vline
и избежать grid
бардак в целом:
ggplot(dat, aes(x, y)) +
geom_point() +
geom_vline(xintercept = c(4, 8)) +
facet_grid(z ~ .) +
xlim(0, 10)