【问题标题】:Changing the geom order in a stacked ggplot legend更改堆叠 ggplot 图例中的几何顺序
【发布时间】:2017-12-05 22:45:20
【问题描述】:

我正在尝试更改我的图例使用 ggplot 为我的图表显示点和线的顺序。

目前,我的图表本身首先显示点,然后在点顶部显示线条,这正是我想要的。这是一个可重现的示例:

ggplot(iris, aes(Sepal.Width, Petal.Width, linetype = Species)) +
  geom_point(aes(colour = Species, shape = Species)) +
  geom_smooth()

从图例中可以看出,它已经按照绘制的顺序覆盖了值,但我想颠倒一下。我知道我可以将点覆盖在图的顶部,如下所示:

ggplot(iris, aes(Sepal.Width, Petal.Width, linetype = Species)) +
  geom_smooth() +
  geom_point(aes(colour = Species, shape = Species)) 

我从here中搜索找到了函数guides(fill = guide_legend(reverse = TRUE)),但是这个没有效果。

非常感谢任何帮助

【问题讨论】:

  • 嗨,贾斯汀,请编辑您的问题并提供一个最小、完整和可验证的示例,特别是重现问题的示例数据集:stackoverflow.com/help/mcve。让帮助你更容易:)
  • 我最终只是重写了这个问题,以便您更好地了解如何为未来构建它。请检查编辑并批准它:)
  • 嗨 Mikey,非常感谢您花时间教我如何正确构建问题并提供一个可验证的示例,我一定会从您的示例中学习并在未来自己做这件事。我绝对批准编辑:)

标签: r ggplot2 legend layer


【解决方案1】:

根据我在 ggplot descriptions 中读到的内容,我不相信这可以设置覆盖 ggplot 图例的顺序。在guides 函数中,您可以使用order 参数设置单独指南的顺序,它对此进行了解释:

"小于99的正整数,指定该指南在多个指南中的顺序。这控制了多个指南的显示顺序,而不是指南本身的内容。如果为0(默认),则顺序由一个秘密算法。”

在我看来,通过以下组合来实现您想要的最容易:

  1. 使用legend=FALSE 抑制某些图例
  2. 多次绘制某些图层。

在下面的示例中,geom_smooth 被绘制了两次。一次创建图例背景,然后第二次覆盖数据。第二次绘制时,不显示图例:

ggplot(iris, aes(Sepal.Width, Petal.Width, linetype = Species)) +
  geom_smooth() +
  geom_point(aes(colour = Species, shape = Species)) +
  geom_smooth(show.legend = FALSE)

另一种方法是使线条颜色随每个数据集而变化。这需要更少的玩耍并且更容易理解,所以我可能会这样做:

ggplot(iris, aes(Sepal.Width, Petal.Width, colour = Species, shape = Species, linetype = Species)) +
  geom_point(aes())  +
  geom_smooth(aes())

【讨论】:

    【解决方案2】:

    这里有两种方法可以控制图例中 grobs 的绘制顺序,但这两种方法都不简单。

    第一个使用ggplot的gtable。布局数据框中的“z”列给出了绘制 grobs 的顺序。但是为了操纵图例的 grobs,必须访问图例本身的布局数据框。像这样的:

    library(ggplot2)
    library(gtable)
    library(grid)
    
    df = read.table(text = 
    "School      Year    Value 
     A           1998    5
     B           1999    10
     C           2000    15
     A           2000    7
     B           2001    15
     C           2002    20", sep = "", header = TRUE)
    
    p <- ggplot(iris, aes(Sepal.Width, Petal.Width, linetype = Species)) +
      geom_point(aes(colour = Species, shape = Species), size = 2) +
      geom_smooth()
    
    # Get the ggplot grob
    gt <- ggplotGrob(p)
    
    # Get the legend
    leg <- gt$grobs[gt$layout$name == "guide-box"][[1]]$grobs[[1]]
    
    # Check the layout
    leg$layout
    

    第 4 行和第 5 行绘制第一个图例键,但它先绘制点 (key-3-1-1),然后绘制线段 (key-3-1-2)。交换 z 值将确保首先绘制线段,然后绘制点。同样,对于第 7 行和第 8 行以及第 10 行和第 11 行。

    # Swap the z-values for the relevant lines in the layout table
    leg$layout[c(4:5, 7:8, 10:11), "z"] <- c(5:4, 8:7, 11:10)
    
    # Put legend back into ggplot grob
    gt$grobs[gt$layout$name == "guide-box"][[1]]$grobs[[1]] <- leg
    
    # Draw it
    grid.newpage()
    grid.draw(gt)
    

    第二种方法使用网格的编辑功能来改变顺序。

    # Get the ggplot grob
    gt <- ggplotGrob(p)
    
    # Get the legend grob
    leg = getGrob(grid.force(gt), gPath("guides"), grep = TRUE)
    
    # Get a list of grobs (in the legend).
    # This also gives the order.
    grid.ls(grid.force(leg))
    
    # Nearly the same names for the grobs, 
    #   and the same order as before 
    #   (don't count the indented grobs).
    
    # Change the order in which grobs are drawn
    leg = reorderGrob(leg,  c(5:4, 8:7, 11:10), back = FALSE)
    
    # Remove the original legend and replace with the new legend
    gt = removeGrob(grid.force(gt), "guides", grep = TRUE)
    gt = addGrob(gt, leg, "guide-box", grep = TRUE)
    
    # Draw the plot
    grid.newpage()
    grid.draw(gt)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-30
      • 1970-01-01
      • 1970-01-01
      • 2020-10-16
      • 1970-01-01
      • 1970-01-01
      • 2019-10-22
      • 2018-02-15
      相关资源
      最近更新 更多