6

Is there a way to make geom_boxplot lines, whiskers, and outlier points inherit the same alpha that is assigned to the boxplot fill in the following plot?

library(ggplot2)

ggplot(iris, aes(x = Species, y = Sepal.Length, alpha = Species == "setosa")) +
  geom_boxplot() +
  scale_alpha_discrete(range = c(0.5, 1))

eipi10
  • 91,525
  • 24
  • 209
  • 285
mdlincoln
  • 274
  • 3
  • 12
  • you might want to take a look at [this question](http://stackoverflow.com/questions/34601194/change-colours-to-defined-palette-for-ggplot-objects) from earlier today – mtoto Jan 05 '16 at 19:05

1 Answers1

5

I'm not sure if there's a natural way to do it within ggplot2, but here's a hacky way: The colour aesthetic determines the colour of the lines, whiskers, and outlier points. So we'll add a colour aesthetic to the plot. However, we'll set the colors manually so that they include the sequence of alpha values in the color definitions. As a result, we effectively add alpha values to the color aesthetic. I've mapped the aesthetics to Species so that I can have three different alpha levels for illustration and added theme_bw() for better contrast of the alpha values.

First, set the alpha values we want in the final graph:

numVals = length(unique(iris$Species))
avals = seq(0.9, 0.3, length.out=numVals)

Here's the hack: Set the all the colors to black, but add the alpha-level sequence to the color definition. For this, we need to convert the the alpha levels to hexadecimal on a 0 - 255 scale.

avalsHex = paste0("#000000", toupper(as.hexmode(round(avals*255))))

In the code above, avals*255 are the alpha levels on a 0 - 255 scale. as.hexmode converts those values to hexadecimal. toupper isn't strictly necessary, but I'm used to seeing hexadecimal color definitions in upper case. Then we paste the two-digit hexadecimal alpha value onto the end of the color, in this case black (#000000), which gives a vector of three colors that include alpha values.

No we plot with both the color and alpha aesthetics and the manual values for each aesthetic:

ggplot(iris, aes(x = Species, y = Sepal.Length)) +
  geom_boxplot(aes(color=Species, alpha = Species)) +
  scale_alpha_manual(values = avals) +
  scale_colour_manual(values = avalsHex)

enter image description here

UPDATE: To address your comment, here's an example with different colors in addition to alpha values:

avalsHex = paste0(c("#FF0000","#00FF00","#0000FF"), toupper(as.hexmode(round(avals*255))))

Then just run the same plotting code to get:

enter image description here

UPDATE 2: Thinking about colors made me realize that you don't even need the conversion to hexadecimal to add on the alpha values. For example, with hcl colors you can do this:

# Black boxplots with 3 different alpha levels
scale_colour_manual(values = hcl(0,0,0, alpha=avals))  

# Colored boxplots with 3 different alpha levels
scale_colour_manual(values=hcl(seq(15,375,length.out=4)[1:3], 100, 65, alpha=avals)) 

The hcl function returns the hexdecimal code for each color, in effect taking care of the conversion for you.

eipi10
  • 91,525
  • 24
  • 209
  • 285
  • Not as hacky as I'd feared! If I had a vector of different fill colors (i.e. not all starting at `#000000`), would this method still work? (sorry, that first sentence got prematurely published) – mdlincoln Jan 05 '16 at 21:53
  • Well, it does maintain the spirit of `ggplot`'s grammar, but you have to go outside the normal ggplot workflow to make it work. – eipi10 Jan 05 '16 at 21:54
  • 1
    To answer the rest of your comment: Yes. You can tack any alpha level you want onto any hexadecimal color by adding the additional two hexadecimal digits. See update for a simple example. – eipi10 Jan 05 '16 at 21:57