从现有的ggplot图表中删除geom?

时间:2018-05-20 11:58:24

标签: r ggplot2

我试图了解如何更改ggplot2图表的内部结构。我开始阅读有关ggplot_builtggplot_gtable的一些资源,但我无法回答下面的问题。

给出g 2 geom的情节。

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

enter image description here

有没有办法潜入g对象并移除一个/多个geoms?

g开始,我可以得到没有地貌的情节吗?

enter image description here

或仅删除geom_text

enter image description here

在更全面地测试答案后更新

我刚注意到移除宝石会对其他宝石的布局产生影响。作为大多数用例的默认和预期行为可能很好,但我实际上需要完全相同的图表&#34; layout&#34; (剩余几何的轴和位置)。

示例,在删除一个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) 

enter image description here

删除一个geom后(请注意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

enter image description here

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

4 个答案:

答案 0 :(得分:16)

您可以像对待其他g对象一样访问/操纵R个元素。

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

enter image description here

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)

enter image description here

答案 1 :(得分:7)

您可以使用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")

答案 2 :(得分: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)

enter image description here

您当然可以在之后添加alpha,如

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

答案 3 :(得分:1)

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

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

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