0

I am trying to make two plots. One shows the boxplots for variable x split by factor category1 and the second plot is the same, but for variable y.

I have provided reproducible code below.

require(ggplot2)

dataset <- data.frame(category1 = rep(LETTERS[1:5], 100),
                  y = rnorm(500, mean = rep(1:5, 100)),
                  z = rnorm(500, mean = rep(c(1:4,NA), 100)))

ggplot(dataset, aes(x=factor(category1), y=y, fill=category1)) + geom_boxplot()
ggplot(dataset, aes(x=factor(category1), y=z, fill=category1)) + geom_boxplot()

The plots are fine, except that I want the colors to carry through, i.e. so that the color for A in category1 is always the same shade of red. I know that ggplot is coloring based on the color wheel divided by 5, and then by 4, respectively, but I don't know how to make it always divide by 5 and use the same color consistently, even though there is no value E in factor z, in the second plot.

scoa
  • 19,359
  • 5
  • 65
  • 80
amoodie
  • 323
  • 2
  • 10
  • you could set the colors manuall: `+ scale_fill_manual(values = palette("default"))` to each plot – scoa Sep 30 '15 at 20:25
  • @scoa, this works. I combined with a method to emulate the ggplot color selection method from [here](http://stackoverflow.com/questions/8197559/emulate-ggplot2-default-color-palette) to produce the desired effect. The solution just doesn't seem very elegant, as much of ggplot does. – amoodie Sep 30 '15 at 20:38
  • How about `scale_fill_discrete(drop = FALSE)` like in [this answer](http://stackoverflow.com/a/21463915/2461552)? There are some more complex answers for more complex situations in [the answers here](http://stackoverflow.com/questions/19068432/ggplot2-how-to-use-same-colors-in-different-plots-for-same-factor). – aosmith Sep 30 '15 at 20:45
  • @ aosmith YES! That seems to do it, I hadn't seen that answer, but another using `scale_fill_discrete` that included a `values` argument I was including that seemed to make it not work. I'll update my answer below to reflect your comment. – amoodie Sep 30 '15 at 20:58

2 Answers2

0

You should set the colors manually to make sure the same palette is used in both plots. Here is an example with the default palette:

+ scale_fill_manual(values = palette("default"))

The package RColorBrewer has elegant predefined palettes that you can browse on their website.

library(RColorBrewer)
ggplot(...) + 
  scale_fill_brewer(palette = "Accent")
scoa
  • 19,359
  • 5
  • 65
  • 80
  • I also like the RColorBrewer colour options. To that end I think `scale_fill_brewer()` can also be used in place of of `scale_fill_manual()`? – tsurudak Sep 30 '15 at 20:56
0

The easiest and most elegant way achieve the desired effect is to use scale_fill_discrete, see example second plot code below:

ggplot(dataset, aes(x=factor(category1), y=z, fill=category1)) +
    geom_boxplot() + scale_fill_discrete(drop=FALSE)

However, it can also be done with the following additional code, which creates a color palette to use in the plotting and then manually sets the colors to use this palette. This solution has the benefit of allowing the user to define any color palette to use as the fixed scheme. The solution follows from code here and an answer from @scoa above.

require(ggplot2)

dataset <- data.frame(category1 = rep(LETTERS[1:5], 100),
                  y = rnorm(500, mean = rep(1:5, 100)),
                  z = rnorm(500, mean = rep(c(1:4,NA), 100)))

n <- length(levels(dataset$category1)) 
hues = seq(15, 375, length=n+1)
cpt <- hcl(h=hues, l=65, c=100)[1:n]

ggplot(dataset, aes(x=factor(category1), y=y, fill=category1)) + 
    geom_boxplot() + scale_fill_manual(values = cpt)
ggplot(dataset, aes(x=factor(category1), y=z, fill=category1)) + 
    geom_boxplot() + scale_fill_manual(values = cpt)
Community
  • 1
  • 1
amoodie
  • 323
  • 2
  • 10