R – How to assign colors to categorical variables in ggplot2 that have stable mapping

ggplot2r

I've been getting up to speed with R in the last month.

Here is my question:

What is a good way to assign colors to categorical variables in ggplot2 that have stable mapping? I need consistent colors across a set of graphs that have different subsets and different number of categorical variables.

For example,

plot1 <- ggplot(data, aes(xData, yData,color=categoricaldData)) + geom_line()

where categoricalData has 5 levels.

And then

plot2 <- ggplot(data.subset, aes(xData.subset, yData.subset, 
                                 color=categoricaldData.subset)) + geom_line()

where categoricalData.subset has 3 levels.

However, a particular level that is in both sets will end up with a different color, which makes it harder to read the graphs together.

Do I need to create a vector of colors in the data frame? Or is there another way to assigns specific colors to categories?

Best Answer

For simple situations like the exact example in the OP, I agree that Thierry's answer is the best. However, I think it's useful to point out another approach that becomes easier when you're trying to maintain consistent color schemes across multiple data frames that are not all obtained by subsetting a single large data frame. Managing the factors levels in multiple data frames can become tedious if they are being pulled from separate files and not all factor levels appear in each file.

One way to address this is to create a custom manual colour scale as follows:

#Some test data
dat <- data.frame(x=runif(10),y=runif(10),
        grp = rep(LETTERS[1:5],each = 2),stringsAsFactors = TRUE)

#Create a custom color scale
library(RColorBrewer)
myColors <- brewer.pal(5,"Set1")
names(myColors) <- levels(dat$grp)
colScale <- scale_colour_manual(name = "grp",values = myColors)

and then add the color scale onto the plot as needed:

#One plot with all the data
p <- ggplot(dat,aes(x,y,colour = grp)) + geom_point()
p1 <- p + colScale

#A second plot with only four of the levels
p2 <- p %+% droplevels(subset(dat[4:10,])) + colScale

The first plot looks like this:

enter image description here

and the second plot looks like this:

enter image description here

This way you don't need to remember or check each data frame to see that they have the appropriate levels.

Related Topic