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))
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)
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With