Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

geom_boxplot: map alpha levels to whiskers & outliers

Tags:

r

ggplot2

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

like image 747
mdlincoln Avatar asked Jan 05 '16 18:01

mdlincoln


1 Answers

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.

like image 138
eipi10 Avatar answered Sep 19 '22 04:09

eipi10