2016-12-01 98 views
3

我一直在構建這個相當複雜的繪圖功能,它構建了一個大型圖形面板,許多圖和層,最近添加的一堆挑戰一直是用二級規模。爲此,我有以下的支撐作用,這會從與有效GGPLOT2對象外面叫...ggplot2:覆蓋兩個圖並使用兩個圖例

overlap_plots <- function(base_plt, over_plt) { 

    plot_theme <- function(p) { 
     plyr::defaults(p$theme, theme_get()) 
    } 

    base_g = ggplot_gtable(ggplot_build(base_plt)) 
    overlay_g = ggplot_gtable(ggplot_build(over_plt)) 

    plt_panel = c(subset(base_g$layout, name == "panel", se = t:r)) 
    pnl_ind = which(overlay_g$layout$name == "panel") 
    leg_ind = which(overlay_g$layout$name == "guide-box") 
    final_grob = gtable_add_grob(base_g, 
      overlay_g$grobs[[pnl_ind]], 
      plt_panel$t, 
      plt_panel$l, 
      plt_panel$b, 
      plt_panel$l) 

    final_grob = gtable_add_grob(final_grob, 
      overlay_g$grobs[[leg_ind]], 
      plt_panel$t, 
      plt_panel$l, 
      plt_panel$b, 
      plt_panel$l) 
    return(final_grob) 
} 

但是,第二次調用gtable_add_grob()並不真正似乎在做任何事情。 ..

對於重現性起見,這裏有兩個隨機地塊...

library(ggplot2) 
library(grid) 
library(gtable) 

d = data.frame(Time = as.POSIXct(seq(1446871740, 1446893340, 60), origin = "1970-01-01"), Value = rnorm(361)) 
base_plt = ggplot() + geom_line(data=d, aes(Time, d[, 2], color="#F564E3")) + 
     scale_color_manual(values = "#F564E3", labels = "#F564E3") + 
     theme(
       plot.margin=unit(c(0,0,0,0), 'cm'), 
       legend.position = c(0, 1), 
       legend.justification = c(0.1, .9)) 
b = data.frame(Time = as.POSIXct(seq(1446871740, 1446893340, 60), origin = "1970-01-01"), Value = rnorm(361)) 
over_plt = ggplot() + geom_line(data=d, aes(Time, b[, 2], color="#00C094")) + 
     scale_color_manual(values = "#00C094", labels = "#00C094") + 
     theme(
       legend.position = c(0, 0), 
       legend.justification = c(0.1, 0.1), 
       panel.background = element_rect(fill = NA), 
       panel.grid.major = element_blank(), 
       panel.grid.minor = element_blank()) 

g = overlap_plots(base_plt, over_plt) 

grid.draw(g) 

回答

3

這個問題可能已經回答過了,但在匆忙我找不到它。

當您使用gtable_add_grob()添加grob時,並且您未指定名稱時,gtable將指定默認名稱「layout」。但是,在你的功能中,這意味着在同一個單元中有兩個同名的grobs。 gtable不喜歡它,只有第一個被繪製。給他們不同的名字:

overlap_plots <- function(base_plt, over_plt) { 

    plot_theme <- function(p) { 
     plyr::defaults(p$theme, theme_get()) 
    } 

    base_g = ggplot_gtable(ggplot_build(base_plt)) 
    overlay_g = ggplot_gtable(ggplot_build(over_plt)) 

    plt_panel = c(subset(base_g$layout, name == "panel", se = t:r)) 
    pnl_ind = which(overlay_g$layout$name == "panel") 
    leg_ind = which(overlay_g$layout$name == "guide-box") 
    final_grob = gtable_add_grob(base_g, 
      overlay_g$grobs[[pnl_ind]], 
      plt_panel$t, 
      plt_panel$l, 
      plt_panel$b, 
      plt_panel$r, name = "a") 

    final_grob = gtable_add_grob(final_grob, 
      overlay_g$grobs[[leg_ind]], 
      plt_panel$t, 
      plt_panel$l, 
      plt_panel$b, 
      plt_panel$r, name = "b") 
    return(final_grob) 
}