在创建后按颜色子集 ggplot2

subsetting a ggplot2 by color after its creation

我有一组要探索的 ggplot。 这些ggplots的制作很复杂,我很难改变它们的制作方式。

我的目标是对图进行子集化以仅显示一个颜色组,就像使用 plotly::ggplotly()(HTML 图)所做的那样。

我希望它应该类似于我们使用 xlim() 将绘图子集化到 x 维度的方式,但对于 color 维度。
然而,似乎它的工作方式似乎并不相同。

这是一个具有预期输出的可重现示例:

library(tidyverse)
p = ggplot(mtcars, aes(mpg, wt, color=factor(cyl))) +
  geom_point()
#initial plot
p

#subset on x
p + lims(x=c(15,20)) #same as xlim(15, 20)
#> Warning: Removed 19 rows containing missing values (geom_point).

#subset on color (fail)
p + lims(color="6")

#expected output (without data manipulation)
ggplot(mtcars %>% filter(cyl==6), 
       aes(mpg, wt, color=factor(cyl))) +
  geom_point()

reprex package (v2.0.1)

于 2022-01-30 创建

如您所见,它没有对颜色进行子集化,而是仅删除了颜色属性。

请注意,x 维度有关于删除值的警告,而 color 维度则没有。

有没有办法在创建图后对其进行子集化?

每个 ggplot 对象都有一个名为 data 的成员,这是一个可以过滤的数据框,因此您可以创建一个基于现有变量进行过滤的小函数:

filter_ggplot <- function(p, predicate) {
  predicate <- match.call()$predicate
  backup    <- p$data
  p$data    <- p$data[with(backup, eval(predicate)),]
  print(p)
  p$data    <- backup
  invisible(p)
}

这允许:

p

p %>% filter_ggplot(cyl == 6)

p %>% filter_ggplot(cyl == 4)

reprex package (v2.0.1)

于 2022-01-30 创建

使用@Allan 的回答和一些 ,我可以 one-liner 解决我的问题:

library(tidyverse)
p = ggplot(mtcars, aes(mpg, wt, color=factor(cyl))) +
  geom_point()
p %+% filter(p$data, cyl==6)

reprex package (v2.0.1)

于 2022-01-30 创建