Search code examples
rggplot2stylesgroupingpoint

distinguish geom_point by two groups


Here's what I got so far:

df<-data.frame(x=(1:100),
               y=rnorm(100),
               Mode=c(rep('Walk',25), rep('Bike',25), rep('Drive',25), rep('Train',25)),
               Location=c(rep(c(rep('City',10), rep('Rural',15)),4)))
ggplot(df)+geom_point(aes(x=x, y=y, col=Mode))+
  scale_color_brewer(palette='Set1')

geom_point plot

I would like to also distinguish the points by Location, more specifically, I want each color divided into two colors, for example, purple as light purple and dark purple, to represent the Locations.

What shall I do?


Solution

  • You have at least two options. One is to assign the color aesthetic to the interaction of the Mode and Location factors in your data frame, like this:

    ggplot(df) + 
    geom_point(aes(x=x, y=y, color=Mode:Location)) + 
    scale_color_manual(values = c('Red', 'Pink', 'Blue', 'LightBlue', 
        'Green', 'LightGreen', 'Black', 'Grey'))
    

    With that approach, ggplot expects a unique color value for every combination of Mode and Location it finds, and each combination is unique from the rest. Thus to get the grouping by color that you want, you will have to define manually the colors you like.

    The other option is as mentioned in the comments, and involves assigning the alpha (transparency) aesthetic to Location and leaving the color Aesthetic set to Mode. That automatically gives the color grouping you want but to my mind creates harder-to-interpret legend.

    ggplot(df) + 
    geom_point(aes(x=x, y=y, color=Mode, alpha=Location)) + 
    scale_alpha_discrete(range = c(0.4, 1)) + 
    scale_color_brewer(palette = 'Set1')
    

    The two results:

    Using Mode:Location Using alpha aesthetic