19

When you have less colours defined with scale_fill_manual than levels in a factor, ggplot2 complains with this error message :

# Basic definition of the plot
plot <- ggplot(s4r, aes(x=DIM, y=nbexpress, fill=DIM))

# Printing plot and options
plot + geom_bar(stat="identity", show_guide=FALSE) + 
  scale_fill_manual(values=c("#CC0000", "#006600", "#669999", "#00CCCC", 
                             "#660099", "#CC0066", "#FF9999", "#FF9900")

Shows:

Error: Insufficient values in manual scale. 10 needed but only 8 provided.

How to avoid this error? It is especially important to me because I work on a server with dynamic data and R embedded in a website CMS and don't want the graphs to fail when there are some wrong levels (this may happen, until we have corrected the database).

So far I've found a workaround (see my answer) but I'm wondering if there is any solution more elegant.

ATN
  • 665
  • 8
  • 26
Joel.O
  • 1,980
  • 3
  • 16
  • 26
  • I'm wondering what is the purpose of a manually defined color scale, if you don't know which categories you have. If you just want different colors for each bar, you maybe could use the `levels` of the `factor`. – ATN Feb 04 '14 at 13:29
  • Actually, in my use case, I do know which categories I have. But then, there can be mistakes of the users, bad spellings... Who will add an unwanted level, not present in the manually defined colors scale, that stops processing the graph with an *ugly* mistake. My workaround is to put some failsafe colors, either than filtering out the unwanted levels... – Joel.O Feb 06 '14 at 16:29
  • I didn't mean you don't know at all what your data look like, I meant due to noise and other factors, the scale is not very usefull. IMHO, better would be `scale_fill_manual(values=c("my.value.1"="white", "my.value.2"="red", ...))` where you define the expected levels, and you can fill up the rest as you wish, don't you think? – ATN Feb 06 '14 at 20:23
  • @ATN Quite often you want to force ggplot to use always the same colors for each factor across different plots. – skan Nov 05 '18 at 15:36

2 Answers2

13

My workaround so far is to provide ggplot2 with more colours, should any more levels appear, like this:

# Basic definition of the plot
plot <- ggplot(s4r, aes(x=DIM, y=nbexpress, fill=DIM))

# Printing plot and options + faceting if any
plot + geom_bar(stat="identity", show_guide=FALSE) + 
  scale_fill_manual(values=c("#CC0000", "#006600", "#669999", "#00CCCC", 
                             "#660099", "#CC0066", "#FF9999", "#FF9900", 
                             "black", "black", "black", "black", "black"))
ATN
  • 665
  • 8
  • 26
Joel.O
  • 1,980
  • 3
  • 16
  • 26
5

Just found a way to fill a palette to the needed size by picking from a given pool.

# count the needed levels of a factor
number <- nlevels(s4r$DIM)

# repeat the given colors enough times
palette <- rep(c("color1", "color2", ...), length.out = number)

# or, if you want a random distribution:
# if you want it random, but reproducable,
# backup .Random.seed, or set your own
set.seed(23)
palette <- sample(c("color1", "color2", ...), number, replace = TRUE)

scale_fill_manual(values=palette)
eMPee584
  • 1,945
  • 20
  • 20