44

I notice that here Box and whiskers plot the call:

p + geom_boxplot(aes(fill = factor(cyl)))

generates bright red/green/blue colors for boxplots fill, while:

p + geom_boxplot(aes(fill = factor(vs)))

Generates a distinct pale green/red of colors. In my data, I get the second set of colors, but would like the first set (like in

p + geom_boxplot(aes(fill = factor(cyl)))

What controls which set of colors ggplot uses and how can you change it?

zx8754
  • 52,746
  • 12
  • 114
  • 209

3 Answers3

56

The default colours are evenly spaced hues around the colour wheel. You can check how this is generated from here.

You can use scale_fill_manual with those colours:

p + scale_fill_manual(values=c("#F8766D", "#00BA38"))

Here, I used ggplot_build(p)$data from cyl to get the colors.

Alternatively, you can use another palette as well like so:

p + scale_fill_brewer(palette="Set1")

And to find the colours in the palette, you can do:

require(RColorBrewer)
brewer.pal(9, "Set1")

Check the package for knowing the palettes and other options, if you're interested.

Edit: @user248237dfsf, as I already pointed out in the link at the top, this function from @Andrie shows the colors generated:

ggplotColours <- function(n=6, h=c(0, 360) +15){
  if ((diff(h)%%360) < 1) h[2] <- h[2] - 360/n
    hcl(h = (seq(h[1], h[2], length = n)), c = 100, l = 65)
}

> ggplotColours(2)
# [1] "#F8766D" "#00BFC4"

> ggplotColours(3)
# [1] "#F8766D" "#00BA38" "#619CFF"

If you look at the two colours generated, the first one is the same, but the second colour is not the same, when n=2 and n=3. This is because it generates colours of evenly spaced hues. If you want to use the colors for cyl for vs then you'll have to set scale_fill_manual and use these colours generated with n=3 from this function.

To verify that this is indeed what's happening you could do:

p1 <- ggplot(mtcars, aes(factor(cyl), mpg)) + 
           geom_boxplot(aes(fill = factor(cyl)))

p2 <- ggplot(mtcars, aes(factor(cyl), mpg)) + 
           geom_boxplot(aes(fill = factor(vs)))

Now, if you do:

ggplot_build(p1)$data[[1]]$fill
# [1] "#F8766D" "#00BA38" "#619CFF"

ggplot_build(p2)$data[[1]]$fill
# [1] "#F8766D" "#00BFC4" "#F8766D" "#00BFC4" "#F8766D"

You see that these are the colours that are generated using ggplotColours and the reason for the difference is also obvious. I hope this helps.

Community
  • 1
  • 1
Arun
  • 116,683
  • 26
  • 284
  • 387
  • 2
    But that doesn't explain why for one variable plotted as a factor you get one set of colors and for different one you get another set of colors like in the doc page I linked to. The colors are evenly spaced, I can see that, but why is it different between the two? I want it to look like the first not the second. –  Feb 28 '13 at 13:35
  • It would be nice to be able to manually set the steps between each color on the hue wheel. That way we could get a greater contrast between consecutive factors. After 360 it should just continue from 0. – JohannesNE May 28 '15 at 10:51
9

Adding to previous answers:

When using the col aesthetic (instead of fill), use scale_color_manual. This is useful for geom_point():

myColors <- c("#56ddc5", "#ff3db7", "#4699dd")
ggplot(mtcars, aes(x=mpg, y=hp, col=as.factor(cyl))) + 
  geom_point() +
  scale_color_manual(values=myColors)

enter image description here

Megatron
  • 15,909
  • 12
  • 89
  • 97
0

you can use these packages:

#install.packages(pals)
#install.packages(reshape2)
require(pals)
require(reshape2)

here you can find some sample dicrete palettes:

pal.bands(alphabet, alphabet2, cols25, glasbey, kelly, okabe, polychrome, 
stepped, stepped2, stepped3, tol, watlington,
        main="Discrete", show.names=FALSE)

and you can apply them like this:

 p +
   scale_fill_manual(values=as.vector(stepped3(20)))