When using ggplot
on objects with large number of groups (e.g. n > 14), most palettes are not able to cope. The function colorRampPalette
is able to extend the range, but to embed it in the scale_fill_manual
, you would need to know the number of unique groups.
Is there a way to automatically extract the number of colours required from ggplot
directly? I have provided an example below, and to make the palette work, I have had to add the number of groups (14) as an argument to scale_fill_manual(values = palette_Dark2(14))
.
Plot using scale_fill_brewer
df <- data.frame(group = paste0("Category", 1:14),
value = 1:28)
library(ggplot2)
ggplot(df, aes(x = group, y = value, fill = group)) +
geom_bar(stat = "identity") +
scale_fill_brewer(palette = "Set1")
Warning message: In RColorBrewer::brewer.pal(n, pal) : n too large, allowed maximum for palette Set1 is 9 Returning the palette you asked for with that many colors
Plot using custom palette
Here I have specified a new colour palette before the plot, which is a colour ramp with 14 steps.
library(RColorBrewer)
palette_Dark2 <- colorRampPalette(brewer.pal(14, "Dark2"))
I then use this in the plot as follows:
ggplot(df, aes(x = group, y = value, fill = group)) +
geom_bar(stat = "identity") +
scale_fill_manual(values = palette_Dark2(14))
Update:
I tried to use length(unique(group))
to extract the number of unique groups but obtained an error message
Error in unique(group) : object 'group' not found
In the attempt of using length(unique(df$group))
, the error message is:
Error: Insufficient values in manual scale. 14 needed but only 1 provided. In addition: Warning message: In brewer.pal(length(unique(df$group)), "Dark2") :n too large, allowed maximum for palette Dark2 is 8 Returning the palette you asked for with that many colors
This is an option, adapting the suggestion from Felix above. First, the palette is made before the plot, with the number of groups extracted from the dataframe:
palette_Dark2 <- colorRampPalette(brewer.pal(14, "Dark2"))
pal <- palette_Dark2(length(unique(df$group)))
ggplot(df, aes(x = group, y = value, fill = group)) +
geom_bar(stat = "identity") +
scale_fill_manual(values = pal)
It still is not perfect, as the palette has to be specified before and requires that the group is selected before the plot. I am hoping that there is a more elegant way that ggplot could just pick this out automatically.
Note: I presume the code is a minimal working example, but the colour specification is actually redundant information in this example, as it provides nothing more than the x axis already displays.
You could do this inside ggplot2 by using scale_fill_identity
and a left_join
to get the column of fill colors mapped to the levels of group
. This solution seems hacky and inelegant to me, but it is a way to create a color palette within ggplot2 that has the right number of colors.
ggplot(df, aes(x = group, y = value,
fill=left_join(data.frame(group),
data.frame(group=unique(group),
fill=palette_Dark2(length(unique(group)))))$fill)) +
geom_bar(stat = "identity") +
scale_fill_identity()
Another possibility is to simply put the entire creation of the palette in scale_fill_manual
ggplot(df, aes(x = group, y = value, fill = group)) +
geom_bar(stat = "identity") +
scale_fill_manual(values = colorRampPalette(brewer.pal(8, "Dark2"))(length(unique(df$group))))
If you do this repeatedly and want to avoid typing of 'df' and 'group' twice, just wrap it in a function, and use aes_string
:
f <- function(df, x, y, group){
ggplot(df, aes_string(x = x, y = y, fill = group)) +
geom_bar(stat = "identity") +
scale_fill_manual(values = colorRampPalette(brewer.pal(8, "Dark2"))(length(unique(df[[group]]))))
}
f(df, "x", "y", "group")
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