2013-11-26 81 views
6

我正在ggplot2中绘制一个包含geom_pointrange和geom_line的图。我看到,当我改变几何的顺序时,要么将点绘制在线的顶部,要么反之亦然。图例也根据geom的相同排序更改了哪个geom被绘制在另一个上面。不过,我想先画一条线,然后在曲线本身的顶部,然后在图例的对面。这可能吗?我会非常感谢任何输入。ggplot2 - 如何更改图例中的geom绘图顺序?

这是我用来制作图形的代码。

md.figd2 <- structure(list(date = c("2013-05-28", "2013-07-11", "2013-09-22", 
"2013-05-28", "2013-07-11", "2013-09-22", "2013-05-28", "2013-07-11", 
"2013-09-22"), trt = structure(c(3L, 3L, 3L, 1L, 1L, 1L, 2L, 
2L, 2L), .Label = c("- Fescue", "- Random", "Control"), class = "factor"), 
means = c(1, 0.921865257043089, 0.793438250521971, 1, 0.878305313846414, 
0.85698797555687, 1, 0.840679145697309, 0.798547331410388 
), mins = c(1, 0.87709562979756, 0.72278951032918, 1, 0.816185624483356, 
0.763720265496049, 1, 0.780804129401513, 0.717089626439849 
), maxes = c(1, 0.966634884288619, 0.864086990714762, 1, 
0.940425003209472, 0.950255685617691, 1, 0.900554161993105, 
0.880005036380927)), .Names = c("date", "trt", "means", "mins", 
"maxes"), row.names = c(NA, 9L), class = "data.frame") 

library(ggplot2) 
dplot1.ysc <- scale_y_continuous(limits=c(0,1), breaks=seq(0,1,.2), name='Proportion mass lost') 
dplot1.xsc <- scale_x_date(limits=as.Date(c('2013-05-23', '2013-10-03')), labels=c('May 28', 'July 11', 'Sep 22'), breaks=md.figdata$date, name='Date') 
dplot1.csc <- scale_color_manual(values=c('grey20','grey50','grey80')) 
dplot1.lsc <- scale_linetype_manual(values=c('solid','dotted','dashed')) 
djitter <- rep(c(0,-1,1), each=3) 

# This one produces the plot with the legend I want. 
dplot1b <- ggplot(md.figd2, aes(x=date + djitter, y=means, group=trt)) + geom_pointrange(aes(ymin=mins, ymax=maxes, color=trt), size=2) + geom_line(aes(linetype=trt), size=1) 
# This one produces the plot with the points on the main plot that I want. 
dplot1b <- ggplot(md.figd2, aes(x=date + djitter, y=means, group=trt)) + geom_line(aes(linetype=trt), size=1) + geom_pointrange(aes(ymin=mins, ymax=maxes, color=trt), size=2) 

dplot1b + dplot1.xsc + dplot1.ysc + dplot1.csc + dplot1.lsc 

回答

3

快速和肮脏的提取:添加其他geom_line WHI ch使用ylim以外的数据,并按照打印顺序将其放在geom_pointrange之后。

# some data for the 'fake' line 
df <- data.frame(date = rep(as.Date(c('2013-05-23', '2013-10-03')), 3), 
       means = 1.5, trt = c("- Fescue", "- Random", "Control")) 

# insert fake line after geom_pointrange 
ggplot(md.figd2, aes(x = date, y = means, group = trt)) + 
    geom_line(aes(linetype = trt), size = 1) + 
    geom_pointrange(aes(ymin = mins, ymax = maxes, color = trt), 
        position = position_dodge(width = 5), size = 2) + 
    geom_line(data = df, aes(linetype = trt), size = 1) + 
    scale_y_continuous(limits = c(0,1), breaks = seq(0,1, 0.2), name = 'Proportion mass lost') + 
    scale_x_date(limits = as.Date(c('2013-05-23', '2013-10-03')), 
       name = 'Date') + 
    scale_color_manual(values = c('grey20','grey50','grey80')) + 
    scale_linetype_manual(values = c('solid','dotted','dashed')) 

enter image description here

请注意,我删除了一些你在我的例子中的情节定制的,部分原因是object 'md.figdata' not found

4

您可以使用gtable::gtable_filter来提取你想要的阴谋的传说,然后gridExtra::grid.arrange重现您想要

# the legend I want 
plot1a <- ggplot(md.figd2, aes(x=date , y=means, group=trt)) + 
    geom_pointrange(aes(ymin=mins, ymax=maxes, color=trt), size=2, 
         position = position_dodge(width=1)) + 
    geom_line(aes(linetype=trt), size=1) 
# This one produces the plot with the points on the main plot that I want. 
dplot1b <- ggplot(md.figd2, aes(x=date, y=means, group=trt)) + 
    geom_line(aes(linetype=trt), size=1) + 
    geom_pointrange(aes(ymin=mins, ymax=maxes, color=trt), size=2) 

w <- dplot1b + dplot1.xsc + dplot1.ysc + dplot1.csc + dplot1.lsc 
# legend 
l <- dplot1a + dplot1.xsc + dplot1.ysc + dplot1.csc + dplot1.lsc 

library(gtable) 
library(gridExtra) 
# extract legend ("guide-box" element) 
leg <- gtable_filter(ggplot_gtable(ggplot_build(l)), 'guide-box') 
# plot the two components, adjusting the widths as you see fit. 
grid.arrange(w + theme(legend.position='none'),leg,ncol=2, widths = c(3,1)) 

另一种方法是简单地更换传说你想在情节的情节与传说你想你已经(使用gtable_filter

# create ggplotGrob of plot you want 
wGrob <- ggplotGrob(w) 
# replace the legend 
wGrob$grobs[wGrob$layout$name == "guide-box"][[1]] <- leg 
grid.draw(wGrob)