【问题标题】:ggplot: plotting layers only if certain criteria are metggplot:仅在满足某些条件时才绘制图层
【发布时间】:2016-03-04 21:25:25
【问题描述】:

有没有一种过滤方法 ggplot 自身内?也就是说我想做这个

p <- ggplot(iris, aes(x = Sepal.Width, y = Sepal.Length, species)) +
     geom_point(size = 4, shape = 4) +
     geom_point(size = 1, shape = 5 # do this only for data that meets some condition. E.g. Species == "setosa") 

我知道我可以使用一些技巧,例如设置 size = 0 if Species != "setosa" 或重置数据,如下所示,但所有技巧都是。

p <- ggplot(iris, aes(x = Sepal.Width, y = Sepal.Length, species)) +
     geom_point(size = 4, shape = 4) +
     geom_point(data = iris %>% filter(Species == "setosa"), colour = "red") +
     geom_point(data = iris %>% filter(Species == "versicolor"), shape = 5)

基本上,我有一个图表,其中只有在满足特定条件时才应该显示某些东西,而现在,我正在使用上面的黑客来完成这个,它让我夜不能寐,我的灵魂慢慢地死于我造成的混乱。不用说,任何帮助将不胜感激!

编辑

恐怕我的例子可能过于简单化了。基本上,给定ggplot(data = ...),我该如何添加这些层,全部使用绑定到 ggplot obj 的数据

  1. 绘制曲线
  2. 在满足标准 #1 的点上绘制点。这些点将是红色的。不符合标准的点不会被绘制(不是像点大小设置为零或 alpha 设置为 0 的 hack)
  3. 为满足条件 #2 的点添加标签。

标准#1 和#2 可以是任何东西。例如。仅标注异常点。仅将超出特定范围的点绘制为红色,等等。

不想想要

  1. 绑定一个新的数据集ala ggplot(data=subset(iris, Species=="setosa"),...)ggplot(data=filter(iris,Species=="setosa")
  2. 使用缩放技巧(例如设置 scale=manual 并且任何不符合条件的都将获得 NULL/NA 等)。例如,如果我有 1000 个点并且只有 1 个点符合给定标准,我希望它只将其绘制逻辑应用于该点,而不是查看和设置所有 1000 个点的样式

【问题讨论】:

  • 典型的选择通常是使您的条件成为图层中的美学,可能同时您自己设置比例。例如。 geom_point(aes(colour = Species == "setosa")) + scale_color_manual(values = c("black", "red")).
  • 另一种方法是使用数据的子集,例如 geom_point(data=subset(iris, Species=="setosa"), size = 1, shape = 5)
  • @lukeA subset 解决方案与filter 解决方案有何不同?
  • @DavidRobinson 请查看我的编辑。从某种意义上说,这仍然看起来像一个 hack,因为我没有告诉 ggplot 仅将特定事物应用于满足特定标准的数据,而是我只是将数据分成两组并以不同的方式设置它们。
  • 你所说的黑客可能基本上是要走的路。如果它运作良好,你为什么需要其他选择? :)

标签: r ggplot2


【解决方案1】:

显然层现在接受一个函数作为数据参数,所以你可以使用它

pick <- function(condition){
  function(d) d %>% filter_(condition)
}

ggplot(iris, aes(x = Sepal.Width, y = Sepal.Length, species)) +
  geom_point(size = 4, shape = 4) +
  geom_point(data = pick(~Species == "setosa"), colour = "red") +
  geom_point(data = pick(~Species == "versicolor"), shape = 5)

【讨论】:

  • 完美。正是我想要的。谢谢巴蒂斯特!
  • 非常好的答案,特别是因为 ggplot2 v2+ 不再支持非官方(即未记录的)subset 参数来过滤每一层的数据。见github.com/hadley/ggplot2/issues/1498
  • 鉴于 filter_ 已弃用,未来可能需要执行以下操作:pick &lt;- function(condition){ function(d) d %&gt;% filter(!!enquo(condition)) }。如果使用了这种习惯用法,则必须从对 pick 调用中的列的引用中删除波浪号。
  • 没有pick 例程有没有办法做到这一点?
【解决方案2】:

您可以使用~ 公式表示法通过匿名函数过滤数据:

library(ggplot2)
library(dplyr)

ggplot(iris, aes(x = Sepal.Width, y = Sepal.Length, species)) +
    geom_point(size = 4, shape = 4) +
    geom_point(data = ~filter(.x, Species == "setosa"), colour = "red") +
    geom_point(data = ~filter(.x, Species == "versicolor"), shape = 5)

reprex package (v2.0.0) 于 2021 年 11 月 15 日创建

【讨论】:

  • 非常酷,感谢您的回答!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多