【问题标题】:Remove geom(s) from an existing ggplot chart?从现有的 ggplot 图表中删除几何图形?
【发布时间】:2018-10-30 06:28:29
【问题描述】:

我正在尝试了解如何更改 ggplot2 图表的内部结构。我开始阅读我能找到的关于ggplot_builtggplot_gtable 的一些资源,但我无法回答以下问题。

给定一个情节 g 和 2 geom

g <- ggplot(iris, aes(Petal.Length, Petal.Width)) + 
  geom_point() + 
  geom_text(aes(label=Sepal.Width))
g

有没有办法深入g 对象并删除一个/多个几何图形?

我可以得到一个从g 开始的没有几何图形的情节吗?

或者只删除geom_text


在对答案进行更彻底的测试后更新

我刚刚注意到删除 geom 会对其他 geom 的布局产生影响。作为大多数用例的默认行为和预期行为可能很棒,但我实际上需要完全相同的图表“布局”(剩余几何图形的轴和位置)。

例如,在移除一个几何图形之前:

library(dplyr)
library(ggplot2)
count(mpg, class) %>%
  mutate(pct=n/sum(n)) %>%
  ggplot(aes(class, pct)) +
  geom_col(fill="blue") +
  geom_line(group=1) +
  geom_point(size=4) 

删除一个几何图形后(请注意,y 轴不再从 0 开始,我猜是没有条形的线/点的默认行为):

library(dplyr)
library(ggplot2)
count(mpg, class) %>%
  mutate(pct=n/sum(n)) %>%
  ggplot(aes(class, pct)) +
  geom_col(fill="blue") +
  geom_line(group=1) +
  geom_point(size=4) -> p
p$layers[[1]] <- NULL
p

有什么方法可以强制 ggplot 保持完全相同的布局?

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    您可以像处理其他 R 对象一样访问/操作 g 的元素。

    g$layers
    #[[1]]
    #geom_point: na.rm = FALSE
    #stat_identity: na.rm = FALSE
    #position_identity 
    
    #[[2]]
    #mapping: label = Sepal.Width 
    #geom_text: parse = FALSE, check_overlap = FALSE, na.rm = FALSE
    #stat_identity: na.rm = FALSE
    #position_identity 
    

    删除geom_text

    g$layers[[2]] <- NULL
    

    删除所有layers

    g$layers <- NULL
    g
    


    gginnards 包提供了一些函数来操作ggplot 层,有关详细信息,请参阅小插图User Guide: 4 Manipulation of plot layers


    编辑

    根据How can I extract plot axes' ranges for a ggplot2 object? 的问题,我找到了一个使用ggplot_buildggplot_gtable 的解决方案。这个想法只是将从ggplot_built(p) 获取的布局参数复制到新绘图,我们为此删除了一个图层。

    # create a copy of p
    p_new <- p
    
    # delete the first layer
    p_new$layers[[1]] <- NULL
    p_new_build <- ggplot_build(p_new)
    
    # this is the important line
    p_new_build$layout$panel_params <- ggplot_build(p)$layout$panel_params
    
    library(gridExtra)
    grid.arrange(p, ggplot_gtable(p_new_build), ncol = 2)
    

    【讨论】:

      【解决方案2】:

      您可以使用gginnards 包让生活更轻松

      library(ggplot2)
      
      ### sample plot w/ both points and labels
      g <- ggplot(iris, aes(Petal.Length, Petal.Width)) + 
        geom_point() + 
        geom_text(aes(label = Sepal.Width))
      g
      

      ### https://cran.rstudio.com/web/packages/gginnards/vignettes/user-guide-2.html
      library(gginnards)
      
      ### remove points
      delete_layers(g, "GeomPoint")
      

      ### remove text
      delete_layers(g, "GeomText")
      

      【讨论】:

      • 非常感谢演示!
      • @Tung 从 0.3.0 版开始,which_layer 函数不再是 ggpmisc 的一部分,而是新包 gginnards 的一部分。最佳
      【解决方案3】:

      您可以尝试包含一些 alpha。它不会显示,而不是删除图层。

      count(mpg, class) %>%
        mutate(pct=n/sum(n)) %>%
        ggplot(aes(class, pct)) +
        geom_col(fill="blue", alpha=0) +
        geom_line(group=1) +
        geom_point(size=4)
      

      你当然可以在之后添加 alpha

      p <- ggplot_build(p)
      p$data[[1]]$alpha <- 0
      plot(ggplot_gtable(p))
      

      【讨论】:

      • 非常感谢,但您能否在现有图表对象的每个几何基础上添加它?
      • 我应该做得更好:这很有帮助:stackoverflow.com/a/41940643/2008527 类似:ggplot_build(p) -&gt; q; q$data[[1]]$alpha &lt;- 0; plot(ggplot_gtable(q))
      • 还发现需要申请p$data[[1]]$size &lt;- 0才能去掉GeomCol的边框之类的东西...
      【解决方案4】:

      构建绘图以解决所有waiver() 内容(轴限制和标签等),对其进行篡改,然后将其转换为gtable 以进行绘图。

      p_built <- ggplot_build(p)
      p_built$plot$layers[[1]] <- NULL
      p_built$data[[1]] <- NULL
      plot(ggplot_gtable(p_built))
      

      请注意,您不仅需要删除图层,还需要删除该图层的数据集。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-09
        • 1970-01-01
        • 2016-09-27
        • 1970-01-01
        相关资源
        最近更新 更多