Search code examples
rcolorsggplot2scalehue

Selecting hue/brewer colours manually in ggplot2


I am trying to produce progressive plots using the ggplot2 library in R.

What I mean by 'progressive' is that, for presentation purposes, I want to add lines to a plot one at a time, so I generate a single plot with many lines multiple times, each with an extra plotted line.

In ggplot2, using scale_colour_hue() for example works well, except that the colours for each line change from plot to plot. I want to keep the colour constant (i.e. plot 1 line 1 has colour X and in plot 5, line 1 still has colour X...etc). I can achieve that by manually declaring colours using scale_colour_manual() but I feel like I'm limited by the aesthetics of these colours ("red", "blue", etc). Do I really have to find the hex value for each of those colours in say the hue palette or is there an easier way out, where I can instruct scale_colour_hue() function to use its palette in a fixed order everytime it adds a new line?

Thanks, appreciate the help!


Solution

  • If you know beforehand the total number of lines you wish to add, you can create a scale with the appropriate colours and names for use with scale_colour_manual

    library(RColorBrewer)
    library(plyr)
    # a function to create a brewer palette of any length (kittens will be killed)
    myBrewerPal <- function(pal = 'Spectral'){
      colorRampPalette(brewer.pal(name = pal, n = 11))
    }
    
    # function to create a named vector of colours for a given 
    # vector x
    create.palette <- function(x, pal = 'Spectral'){
      ux <- sort(unique(x))
      n <- length(ux)
      setNames(myBrewerPal(pal)(n), ux)
    
    }
    
    # create a manual scale with the named values part
    myPal <- scale_colour_manual(name = 'Gear', values = create.palette(factor(mtcars$gear)))
    
    
    # the base plot (no lines)
    baseplot <- ggplot(mtcars, aes(x=hp, y = disp, colour = factor(gear))) + myPal
    # 1 line
    baseplot + geom_line(subset = .(gear==3))
    

    enter image description here

    # 2 lines (gear = 3 is consistent)
    baseplot + geom_line(subset = .(gear %in% 3:4))
    

    enter image description here