Search code examples
rggplot2line-plot

How to colour multiple subclasses with similar colours in ggplot lineplot?


So, as in the question, I have this dataframe which is also plotted:

library("ggplot2")
set.seed(1278)
classes <- c("a1", "a2", "a3", "a4", "b1", "b2", "b3", "b4", "b5", "c1", "c2", "c3")
kinds <- c("WWW", "XXX", "YYY", "ZZZ", "QQQ", "VVV")
values <- seq(1:100)

vK <- vector()
vC <- vector()
vals <- vector()
for (k in kinds) {
    vK <- append(vK, rep(k, length(classes)))
    vC <- append(vC, classes)
    vals <- append(vals, sample(values, length(classes), replace=T))
}

df <- cbind.data.frame(vC, vK, vals)
colnames(df) <- c("class", "kind", "value")

ggplot(data=df, aes(x=kind, y=value, group=class, color=class)) + geom_line()

Problem is that each class is represented by a different colour which reflect the number, i.e. the subclass, in the variable, i.e. a1, a2 etc. What I need is to plot each class with a similar color. In this example we have 3 actual classes, i.e. "a", "b", and "c". Is there a way to colour "a" with sort of different red shades for the subclasses 1, 2, 3..., "b" with different blue shades etc...

I tried something like this but it didn't work out since the classes lost the subclasses :

df$class <- as.factor(gsub("1|2|3|4|5|6|7|8|9|0", "", df$class))

ggplot(data=df, aes(x=kind, y=value, group=class, color=class)) + geom_line()

It means that I need to keep the subclasses.

I am open to different plots too!


Solution

  • You approach was right. Simply add two additional variables, one for the super-class, one for the subclass. The shading of the subclasses you had in mind cound for example achieved using the alpha aesthetic. Try this:

    library("ggplot2")
    set.seed(1278)
    classes <- c("a1", "a2", "a3", "a4", "b1", "b2", "b3", "b4", "b5", "c1", "c2", "c3")
    kinds <- c("WWW", "XXX", "YYY", "ZZZ", "QQQ", "VVV")
    values <- seq(1:100)
    
    vK <- vector()
    vC <- vector()
    vals <- vector()
    for (k in kinds) {
      vK <- append(vK, rep(k, length(classes)))
      vC <- append(vC, classes)
      vals <- append(vals, sample(values, length(classes), replace=T))
    }
    
    df <- cbind.data.frame(vC, vK, vals)
    
    colnames(df) <- c("class", "kind", "value")
    
    df$class1 <- as.factor(gsub("[0-9]", "", df$class))
    df$subclass1 <- as.factor(gsub("[a-z]", "", df$class))
    df$subclass1 <- as.numeric(df$subclass1)
    
    ggplot(data=df, aes(x=kind, y=value, group=class, color=class1, alpha = subclass1)) + 
      geom_line() +
      scale_alpha_continuous(range = c(.5, 1))
    

    Created on 2020-03-31 by the reprex package (v0.3.0)