如何在ggplot独立定位两个传说(How do I position two legends in

2019-06-18 17:04发布

标题很好覆盖它。

我有两个传说,关于大小和颜色,并希望有一个,比方说,在顶部,一个在图形中。

这是可能的,如果是这样,怎么

TIA

Answer 1:

从我的理解,基本上都超过了传说非常有限的控制ggplot2 。 下面是从哈德利的书(第111页)一个段落:

GGPLOT2尝试使用传说的最小可能数准确地表达在情节中使用的美观性。 它通过一个变量与多于一个美学使用结合图例执行此操作。 图6.14示出了用于点的geom这样一个例子:如果两个颜色和形状被映射到相同的变量,那么只有一个单一的图例是必要的。 为了传说中要合并,它们必须具有相同的名称(相同的图例标题)。 出于这个原因,如果你改变了合并的传说之一的名字,你需要改变它的所有的人。



Answer 2:

它可以通过从图中提取分离的传说,然后安排在相关情节的传说来完成。 这里的代码使用功能从gtable包做了提取,然后从功能gridExtra包做安排。 其目的是有一个包含色彩的传说和传说大小的阴谋。 首先,提取只包含色彩传奇的情节色彩的传说。 其次,提取仅包含大小传说情节大小传奇。 三,画不包含传奇的阴谋。 第四,安排情节和两个传说成一个新的情节。

# Some data
df <- data.frame(
  x = 1:10,
  y = 1:10,
  colour = factor(sample(1:3, 10, replace = TRUE)),
  size = factor(sample(1:3, 10, replace = TRUE)))

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

    ### Step 1
# Draw a plot with the colour legend
(p1 <- ggplot(data = df, aes(x=x, y=y)) +
   geom_point(aes(colour = colour)) +
   theme_bw() +
   theme(legend.position = "top"))

# Extract the colour legend - leg1
leg1 <- gtable_filter(ggplot_gtable(ggplot_build(p1)), "guide-box") 

    ### Step 2
# Draw a plot with the size legend
(p2 <- ggplot(data = df, aes(x=x, y=y)) +
   geom_point(aes(size = size)) +
   theme_bw())

# Extract the size legend - leg2
leg2 <- gtable_filter(ggplot_gtable(ggplot_build(p2)), "guide-box") 

    # Step 3
# Draw a plot with no legends - plot
(plot <- ggplot(data = df, aes(x=x, y=y)) +
   geom_point(aes(size = size, colour = colour)) +
   theme_bw() +
   theme(legend.position = "none"))

    ### Step 4
# Arrange the three components (plot, leg1, leg2)
# The two legends are positioned outside the plot: 
# one at the top and the other to the side.
plotNew <- arrangeGrob(leg1, plot, 
         heights = unit.c(leg1$height, unit(1, "npc") - leg1$height), ncol = 1)

plotNew <- arrangeGrob(plotNew, leg2,
          widths = unit.c(unit(1, "npc") - leg2$width, leg2$width), nrow = 1)

grid.newpage()
grid.draw(plotNew)

# OR, arrange one legend at the top and the other inside the plot.
plotNew <- plot + 
        annotation_custom(grob = leg2, xmin = 7, xmax = 10, ymin = 0, ymax = 4)

plotNew <- arrangeGrob(leg1, plotNew,
     heights = unit.c(leg1$height, unit(1, "npc") -  leg1$height), ncol = 1)

grid.newpage()
grid.draw(plotNew)



Answer 3:

下面是一个使用另一种解决方案ggplot2cowplot (= GGPLOT2扩展)包。

该方法类似于桑迪斯之一,因为它取出传说作为单独的对象,让你独立完成的位置。 它是primarly设计属于两个或多个地块的地块网格多个图例。

功能g_legend ,这是赫比使用,从其中取出的答案 。

这个想法是如下:

  1. 没有传说中创建Plot1,Plot2,...,PlotX
  2. 传说中创建Plot1,Plot2,...,PlotX
  3. 来自步骤2到单独的对象提取的传说
  4. 成立传说电网和安排他们的传说路要
  5. 创建网格相结合的情节和传说

这似乎有点复杂,时间/码comsuming但设置一次,你能适应,并用它为每一种剧情/传奇定制。

 library(ggplot2) library(cowplot) # set up function g_legend<-function(a.gplot){ tmp <- ggplot_gtable(ggplot_build(a.gplot)) leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box") legend <- tmp$grobs[[leg]] return(legend) } # Some data df <- data.frame( Name = factor(rep(c("A", "B", "C"), 12)), Month = factor(rep(1:12, each=3)), Temp = sample(0:40, 12), Precip = sample(50:400, 12)) # create plot1 plot1 <- ggplot(df, aes(Month, Temp, fill = Name)) + geom_point(show.legend = F, aes(group = Name, colour = Name), size = 3, shape = 17) + geom_smooth(method = "loess", se = F, aes(group = Name, colour = Name), show.legend = F, size = 0.5, linetype = "dashed") # create plot2 plot2 <- ggplot(df, aes(Month, Precip, fill = Name)) + geom_bar(stat = "identity", position = "dodge", show.legend = F) + geom_smooth(method = "loess", se = F, aes(group = Name, colour = Name), show.legend = F, size = 1, linetype = "dashed") + scale_fill_grey() # create legend1 legend1 <- ggplot(df, aes(Month, Temp)) + geom_point(show.legend = T, aes(group = Name, colour = Name), size = 3, shape = 17) + geom_smooth(method = "loess", se = F,aes(group = Name, colour = Name), show.legend = T, size = 0.5, linetype = "dashed") + labs(colour = "Station") + theme(legend.text=element_text(size=8), legend.title = element_text(face = "italic", angle = -0, size = 10)) # create legend2 legend2 <- ggplot(df, aes(Month, Precip, fill = Name)) + geom_bar(stat = "identity", position = "dodge", show.legend = T) + scale_fill_grey() + guides(fill = guide_legend(title = "", title.theme = element_text(face = "italic", angle = -0, size = 10))) + theme(legend.text=element_text(size=8)) # extract "legends only" from ggplot object legend1 <- g_legend(legend1) legend2 <- g_legend(legend2) # setup legends grid legend1_grid <- cowplot::plot_grid(legend1, align = "v", nrow = 2) # add second legend to grid, specifying its location legends <- legend1_grid + ggplot2::annotation_custom(grob = legend2, xmin = 0.5, xmax = 0.5, ymin = 0.55, ymax = 0.55) # plot "plots" + "legends" (with legends in between plots) cowplot::plot_grid(plot1, legends, plot2, ncol = 3, rel_widths = c(0.45, 0.1, 0.45)) 

例子:

例如http://i65.tinypic.com/jl1lef.png

改变最终的顺序plot_grid()调用将传说中的权利:

cowplot::plot_grid(plot1, plot2, legends, ncol = 3, 
                   rel_widths = c(0.45, 0.45, 0.1))

例题http://i68.tinypic.com/314yn9i.png



文章来源: How do I position two legends independently in ggplot
标签: r ggplot2 legend