r - ggplot2:手动添加图例

标签 r ggplot2 legend

如何将任何(不相关的)图例映射到现有的ggplot?

免责声明:请不要恨我。我知道用“ggplot2”创建图例的最佳方法是正确映射数据,而我有99%的时间都这样做。但是在这里,我要求提供一些可以给我我想要的任何传说的东西。

举例来说,我有一个看起来像这样的情节:
enter image description here

通过以下代码创建:

set.seed(42)
temp1 = cbind.data.frame(begin = rnorm(10, 0, 1), end = rnorm(10, 2, 1), y1 = 1:10, y2 = 1:10, id = as.character(1:10))
temp2 = cbind.data.frame(x = 0:2, y = 1:3*2)
temp3 = cbind.data.frame(x = seq(0.5, 1.5, 0.33))
temp = c()
plot1 = ggplot(data = temp, aes(x = x)) + 
  geom_vline(data = temp3, aes(xintercept = x), color = "red", linetype = "longdash") + 
  geom_segment(data = temp1, aes(y = y1, yend = y2, x = begin, xend = end, color = id)) +
  geom_point(data = temp2, aes(x = x, y = y), shape = 4, size = 4) +
  scale_color_discrete(guide = F) 
plot1

我想添加一个图例,其中包含:
  • 称为“l1”的红色长点垂直线
  • 黑色实心水平线,称为“l2”
  • 一个名为“l3”的绿色填充块

  • 理想情况下,我会产生如下所示的代码(前面的伪代码):
    plot2 = plot1 + guide(elements = list(list(type = "line", color = "red", linetype = "longdash", direction = "vertical", label = "l1"), list(type = "line", label = "l2"), list(type = "rect", fill = "green", label = "l3"))
    

    我最好的猜测是如何创建一些辅助伪数据temp,将其绘制/映射到情节上不可见的某个地方,然后用于创建图例,但是我没有成功获得类似的东西来绘制我的图例。

    再一次,我的想法是如何在现有绘图中添加任何不相关的图例,即如何不将原始数据巧妙地映射到绘图变量?

    最佳答案

    可以从头开始构建图例:使用grid构造图例的元素;然后使用gtable将元素放置在图例中,并将图例放置在绘图中。这有点粗糙,但是给出了总体思路。

    set.seed(42)
    temp1 = cbind.data.frame(begin = rnorm(10, 0, 1), end = rnorm(10, 2, 1), y1 = 1:10, y2 = 1:10, id = as.character(1:10))
    temp2 = cbind.data.frame(x = 0:2, y = 1:3*2)
    temp3 = cbind.data.frame(x = seq(0.5, 1.5, 0.33))
    temp = c()
    
    library(ggplot2)  
    library(grid)  
    library(gtable)  
    
    plot1 = ggplot(data = temp, aes(x = x)) + 
      geom_vline(data = temp3, aes(xintercept = x), color = "red", linetype = "longdash") + 
      geom_segment(data = temp1, aes(y = y1, yend = y2, x = begin, xend = end, color = id)) +
      geom_point(data = temp2, aes(x = x, y = y), shape = 4, size = 4) +
      scale_color_discrete(guide = F) 
    
    
    # Construct the six grobs - three symbols and three labels
    L1 = linesGrob(x = unit(c(.5, .5), "npc"), y = unit(c(.25, .75), "npc"),
       gp = gpar(col = "red", lty = "longdash"))
    L2 = linesGrob(x = unit(c(.25, .75), "npc"), y = unit(c(.5, .5), "npc"))
    L3 = rectGrob(height = .5, width = .5, gp = gpar(fill = "green", col = NA))
    T1 = textGrob("l1", x = .2, just = "left")
    T2 = textGrob("l2", x = .2, just = "left")
    T3 = textGrob("l3", x = .2, just = "left")
    
    # Construct a gtable - 2 columns X 4 rows
    leg = gtable(width = unit(c(1,1), "cm"), height = unit(c(1,1,1,1), "cm"))
    leg = gtable_add_grob(leg, rectGrob(gp = gpar(fill = NA, col = "black")), t=2,l=1,b=4,r=2)
    
    # Place the six grob into the table
    leg = gtable_add_grob(leg, L1, t=2, l=1)
    leg = gtable_add_grob(leg, L2, t=3, l=1)
    leg = gtable_add_grob(leg, L3, t=4, l=1)
    leg = gtable_add_grob(leg, T1, t=2, l=2)
    leg = gtable_add_grob(leg, T2, t=3, l=2)
    leg = gtable_add_grob(leg, T3, t=4, l=2)
    
    # Give it a title (if needed)
    leg = gtable_add_grob(leg, textGrob("Legend"), t=1, l=1, r=2)
    
    # Get the ggplot grob for plot1
    g = ggplotGrob(plot1)
    
    # Get the position of the panel,
    # add a column to the right of the panel, 
    # put the legend into that column, 
    # and then add another spacing column
    pos = g$layout[grepl("panel", g$layout$name), c('t', 'l')]
    g = gtable_add_cols(g, sum(leg$widths), pos$l)
    g = gtable_add_grob(g, leg, t = pos$t, l = pos$l + 1)
    g = gtable_add_cols(g, unit(6, "pt"), pos$l)
    
    # Draw it
    grid.newpage()
    grid.draw(g)
    

    enter image description here

    关于r - ggplot2:手动添加图例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34829284/

    相关文章:

    r - 在R中更改月份全名的德国月份缩写

    r - 将两个 ggplots 合并为一个具有共享图例的图

    r - ggplot 和 geom_text()

    R-将值添加到符合特定条件的数据框

    r - 逐步完成具有中间结果的管道

    r - 如何使用 ggplot2 在直方图中添加汇总统计信息?

    python - matplotlib 图例 : How to specify font weight?

    r - 如何添加图例以使用来自多个数据框的数据进行绘图

    python - 图例中的分割标记和线条 - Matplotlib

    r - 强制ggplot2的y轴标签只能是整数,并给出适当的间隔