Boxplot, how to match outliers' color to fill aesthetics?

后端 未结 4 1116
独厮守ぢ
独厮守ぢ 2020-12-15 20:22

I am trying to match boxplot\'s outliers color to the fill color which is set by aesthetic (scale_colour_discrete).

Here is an example.

m <- ggplo         


        
相关标签:
4条回答
  • 2020-12-15 21:01

    As @koshke said, having the outliers colored like the lines of the box (not the fill color) is now easily possible by setting 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()
    

    boxplot with coloured outliers

    • outlier.colour must be written with "ou"
    • outlier.colour must be outside aes ()

    I'm posting this as a late answer because I find myself looking this up again and again, and I also posted it for the related question Coloring boxplot outlier points in ggplot2?.

    0 讨论(0)
  • 2020-12-15 21:01

    I had a very similar issue. I wanted to match style with a previous plot, so wanted black borders with coloured fill, and matching outliers.

    My solution was to over-print , once with colour= and the default solid circle point, and once with fill= and an open circle point-shape

    p <- ggplot(mtcars, aes(factor(cyl), mpg))
    p + geom_boxplot(aes(colour=factor(cyl))) + 
        geom_boxplot(aes(fill=factor(cyl)), outlier.shape=21)
    

    boxplot with coloured fill, and black borders and median line

    0 讨论(0)
  • 2020-12-15 21:02

    I found a solution to the fact that setting geom_boxplot(outlier.colour = NULL) doesn't work anymore in newest versions of R (@jonsnow speaks about version 1.0.0 of ggplot2).

    In order to replicate the behaviour that @cbeleites propsed you simply need to use the following code:

    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()
    

    as expected this produces plot with points that match the line color.

    Of course one should remember to restore the default if he needs to draw multiple plots:

    update_geom_defaults("point", list(colour = "black"))
    

    The solution was found by reading the ggplot2 changelog on github:

    The outliers of geom_boxplot() use the default colour, size and shape from geom_point(). Changing the defaults of geom_point() with update_geom_defaults() will apply the same changes to the outliers of geom_boxplot(). Changing the defaults for the outliers was previously not possible. (@ThierryO, #757)

    Posted here as well: Coloring boxplot outlier points in ggplot2?

    0 讨论(0)
  • 2020-12-15 21:07

    I found a way to do this, editing raw grid object.

    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

    0 讨论(0)
提交回复
热议问题