ggplot2:叠加两个图并使用两个图例

时间:2016-12-01 01:28:58

标签: r 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)

1 个答案:

答案 0 :(得分:3)

此问题之前可能已经得到解答,但我无法赶时间找到。

使用gtable_add_grob()添加grob并且未指定名称时,gtable会指定默认名称&#34; layout&#34;。但是,在您的函数中,这意味着一个单元格中具有相同名称的两个grob。 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)
}