箱线图,如何将异常值的颜色与填充美学匹配?

17

我想将箱线图(boxplot)的异常值颜色与美学设置的填充颜色(scale_colour_discrete)匹配。

这是一个例子。

m <- ggplot(movies, aes(y = votes, x = factor(round(rating)),
    fill=factor(Animation)))
m + geom_boxplot() + scale_y_log10()

以下代码生成了下图。我该如何将这些黑点改成正文中使用的红色/绿色颜色?如果我理解正确,箱线图的outlier.colour选项似乎只能选择一种颜色,而且不太美观。如果有需要,我可以使用颜色美学来实现。

原始版本


编辑:

参考这个解决方案(更改geom_boxplot中的whisker定义)。 stats_summary重置了水平闪避,我无法弄清楚如何重新获取它。因为现在我知道该怎么做,所以可能会删除异常值并根据需要拉伸盒须。

# define the summary function
f <- function(x) {
  r <- quantile(x, probs = c(0.05, 0.25, 0.5, 0.75, 0.95))
  names(r) <- c("ymin", "lower", "middle", "upper", "ymax")
  r
}
# define outlier function, beyound 5 and 95% percentiles
o <- function(x) {
  subset(x, x < quantile(x,probs=c(0.05))[1] | quantile(x,probs=c(0.95))[1] < x)
}

m <- ggplot(movies, aes(y = votes, x = factor(round(rating)),
    colour=factor(Animation)))
m <- m + stat_summary(fun.data=f, geom='boxplot')
m <- m + stat_summary(fun.y=o, geom='point', aes(colour=factor(Animation)))
m + scale_y_log10()

尝试失败


1
这在当前版本中是不可能的,但在下一个版本中将会实现。 - kohske
@kohske,也许你可以将你的评论转化为一个答案。如果yosukesabai接受了这个答案,那么SO社区就清楚地知道这个问题已经解决了。(而且你还能获得一些声望值:))。 - Paul Hiemstra
实际上,我发现了kohske的答案"Changing whisker definition in geom_boxplot",这可能可以用来解决我的问题。希望它不会太麻烦... - yosukesabai
@kohske,您能详细说明新版本中会修复什么问题以及时间框架吗?我希望在离散的x轴比例尺下,位置='dodge'可以适用于不同的几何形状。这是正在进行的工作吗? - yosukesabai
1
@JoshO'Brien,我认为我的“解决方案”是不能接受的...一旦我想出如何分开这两个数据集,我会按照你说的做。谢谢你的评论。 - yosukesabai
显示剩余2条评论
4个回答

11

正如 @koshke 所说,通过设置 outlier.colour = NULL,现在可以轻松地将异常值的颜色设为盒须的线条颜色(而不是填充颜色):

m <- ggplot(movies, aes(y = votes, x = factor(round(rating)),
    colour = factor(Animation)))
m + geom_boxplot(outlier.colour = NULL) + scale_y_log10()

带有彩色异常值的箱线图

  • outlier.colour必须用“ou”拼写。
  • outlier.colour必须放在aes()之外。

我将此发布为一个晚回答,因为我发现自己一次又一次地查找它,并且我还发布了相关问题的答案(在ggplot2中对箱线图异常值点着色?)


我在接受你的答案之前尝试检查它是否有效,但不知何故我的 R 安装出了问题。我相信你,所以我已经将其接受为答案! - yosukesabai
@yosukesabai:对于旧问题,没有必要急于接受晚回答。希望你已经成功安装了。 - cbeleites unhappy with SX
请注意,这与OP的标题所暗示的填充颜色不匹配,但它确实与轮廓/线条颜色匹配 - 这正是我所需要的。+1 - RyanStochastic
@RyanStochastic:你说得对 - 我只是从另一篇帖子中复制的。不过,设置填充颜色很简单。 - cbeleites unhappy with SX
11
似乎这个解决方案不再适用于ggplot2 1.0.0和R 3.1.1。有什么办法可以为新版本获取匹配的异常值颜色? - Jon Snow
在ggplot2 2.2.1中,似乎只需要指定aes(...,color = some_factor_level)就可以实现这种效果,不需要outlier.colour = NULL - user5359531

5

我找到了一个解决最新版本R中无法设置 geom_boxplot(outlier.colour = NULL)的方法(@jonsnow在谈论ggplot2的1.0.0版本)。

为了复制@cbeleites所建议的行为,你只需要使用以下代码:

update_geom_defaults("point", list(colour = NULL))
m <- ggplot(movies, aes(y = votes, x = factor(round(rating)),
            colour = factor(Animation)))
m + geom_boxplot() + scale_y_log10()

正如预期的那样,这将产生与线条颜色匹配的点的图表。
当然,如果需要绘制多个图表,则应记住恢复默认设置:
update_geom_defaults("point", list(colour = "black"))

解决方案是在github上阅读ggplot2 changelog

geom_boxplot()的离群值使用geom_point()的默认颜色、大小和形状。使用update_geom_defaults()更改geom_point()的默认值将同时应用于geom_boxplot()的离群值。以前无法更改离群值的默认值。(@ThierryO, #757)

也在此发布:如何在ggplot2中为箱线图的离群点着色?


4
我找到了一种方法来完成这个操作,需要编辑原始的网格对象。
library(ggplot2)

match.ol.col <- function(plt,aes.cp='fill') {
  # matches outliers' color to either fill or colour aesthetics
  #   plt: ggplot layer object having boxplot
  #   aes.cp: aetsthetic from which copy color.  must be either 'fill' or 'col'
  # returns grid objects, so print it wigh grid.draw(), not print()
  if (aes.cp %in% c('color', 'colour')) aes.cp <- 'col'
  grob <- ggplotGrob(plt)
  bps <- getGrob(grob, 'boxplots', grep=T)
  for (bp in bps$children) {
    p <- getGrob(bp, 'point', grep=T)
    if (is.null(p)) next
    r <- getGrob(bp, 'rect', grep=T)
    grob <- geditGrob(grob, p$name, gp=gpar(col=r$gp[[aes.cp]]))
  }
  return(grob)
}


m <- ggplot(movies, aes(y = votes, x = factor(round(rating)),
    colour=factor(Animation)))
p <- m + geom_boxplot() + scale_y_log10()

grob <- match.ol.col(p, aes.cp='colour')
grid.draw(grob)

results:

demobox.png


1
我遇到了一个非常相似的问题。我想要与之前的图形匹配样式,所以想要黑色边框和彩色填充,并且匹配异常值。
我的解决方案是进行重叠打印,一次使用color =和默认的实心圆点,一次使用fill =和空心圆点形状。
p <- ggplot(mtcars, aes(factor(cyl), mpg))
p + geom_boxplot(aes(colour=factor(cyl))) + 
    geom_boxplot(aes(fill=factor(cyl)), outlier.shape=21)

带有填充颜色、黑边框和中位数线的箱型图


在第二个 geom_boxplot 调用中,您还可以执行 outlier.colour = NA - bmayer
1
使用 ggplot2 2.2.1 版本,我发现不需要进行覆盖打印。只需使用 p + geom_boxplot(aes(fill=factor(cyl)), outlier.shape=21) 即可获得与箱子填充颜色相匹配的异常值点填充颜色。 - Michael S Taylor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接