На странице Как я могу поместите преобразованную шкалу в правую часть ggplot2? было показано, как добавить две оси Y в один и тот же график, манипулируя и объединяя объекты ggplot2 с gtable. Из приведенного здесь примера мне удалось расширить его для работы с facet_wrap. См. Пример ниже.
Однако есть три вещи, которые не идеальны.
- Шкала всегда ставится крайним правым. Было бы лучше, если бы это было связано с сюжетом в последней строке
- Это не сработает, если ось Y есть на всех графиках отдельно (т.е. вы помещаете
scales="free_y"
вfacet_wrap
) - Если я оставлю линии сетки (закомментированная линия), линии сетки из вторых графиков появятся перед первым графиком.
Есть идеи, есть ли умный способ исправить эти, по общему признанию, небольшие проблемы?
library(ggplot2)
library(gtable)
library(grid)
p1 <- ggplot(diamonds, aes(y=carat,x=price))
p1 <- p1 + geom_point(color="red")
p1 <- p1 + facet_wrap(~ color)
p1 <- p1 + theme_bw() %+replace% theme(panel.background = element_rect(fill = NA)) # use white theme and set bg to transparent so they can merge nice
#p1 <- p1 + theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank()) # remove gridlines
p1
p2 <- ggplot(diamonds, aes(x=price))
p2 <- p2 + geom_histogram( binwidth = 1000)
p2 <- p2 + facet_wrap(~ color)
p2 <- p2 + theme_bw() %+replace% theme(panel.background = element_rect(fill = NA))
#p2 <- p2 + theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank())
p2
## Putting plots together ##################
# extract gtable
g1 <- ggplot_gtable(ggplot_build(p1))
g2 <- ggplot_gtable(ggplot_build(p2))
# overlap the panel of 2nd plot on that of 1st plot
pp <- c(subset(g1$layout, grepl("panel",name) , se = t:r))
g <- gtable_add_grob(g1, g2$grobs[grep("panel",g2$layout$name)], pp$t,
pp$l, pp$b, pp$l)
# axis tweaks
ia <- which(grepl("axis_l",g2$layout$name) | grepl("axis-l",g2$layout$name) )
ga <- g2$grobs[ia]
axis_idx <- as.numeric(which(sapply(ga,function(x) !is.null(x$children$axis))))
for(i in 1:length(axis_idx)){
ax <- ga[[axis_idx[i]]]$children$axis
ax$widths <- rev(ax$widths)
ax$grobs <- rev(ax$grobs)
ax$grobs[[1]]$x <- ax$grobs[[1]]$x - unit(1, "npc") + unit(0.15, "cm")
g <- gtable_add_cols(g, g2$widths[g2$layout[ia[axis_idx[i]], ]$l], length(g$widths) - 1)
g <- gtable_add_grob(g, ax, pp$t[axis_idx[i]], length(g$widths) - i, pp$b[axis_idx[i]])
}
# Plot!
grid.newpage()
grid.draw(g)