Search code examples
rcolorscorrelationscatter-plot

ggpairs : Colouring the geoms by a Factor


I am trying to replicate with ggpairs what can be accomplished easily in pairs -- i.e. to colour the geoms (e.g. scatter points etc) by a binary Factor (which represents a Class). But I can not. Below is a reproducible example using the dataset Smarket from the library ISLR:

library(ISLR)
data(Smarket)
pairs(Smarket, col = Smarket$Direction)

This returns the following graph:

enter image description here

Now, using ggpairs without specifying the colour by Class I get the following plot:

Smarket$Class <- ifelse(Smarket$Direction == "Up", 1, -1)

ggpairs(Smarket %>% select(-9) , 
        lower = list(continuous = wrap("points", color = "red", alpha = 0.5), 
                     combo = wrap("box", color = "blue", alpha = 0.3), 
                     discrete = wrap("facetbar", color = "orange", alpha = 0.3) ), 
        diag = list(continuous = wrap("densityDiag",  color = "yellow", alpha = 0.5) ))

enter image description here

But my attempts to colour the geoms by Class fail:

> color_by_Class <- as.factor(ifelse(Smarket$Direction == "Up", "red", "black"))
> ggpairs(Smarket %>% select(-9) , 
+         lower = list(continuous = wrap("points", color = color_by_Class, alpha = 0.5), 
+                      combo = wrap("box", color = "orange", alpha = 0.3), 
+                      discrete = wrap("facetbar", color = color_by_Class, alpha = 0.3) ), 
+         diag = list(continuous = wrap("densityDiag",  color = color_by_Class, alpha = 0.5) ))
Error: Aesthetics must be either length 1 or the same as the data (512): colour, alpha
> length(color_by_Class)
[1] 1250
> dim(Smarket %>% select(-9))
[1] 1250    8

or

> ggpairs(Smarket %>% select(-9) , 
+         lower = list(continuous = wrap("points", aes(color = color_by_Class), alpha = 0.5), 
+                      combo = wrap("box", aes(color = color_by_Class), alpha = 0.3), 
+                      discrete = wrap("facetbar", aes(color = color_by_Class), alpha = 0.3) ), 
+         diag = list(continuous = wrap("densityDiag",  aes(color = color_by_Class), alpha = 0.5) ))
Error in wrap("points", aes(color = color_by_Class), alpha = 0.5) : 
  all parameters must be named arguments

Your advice will be appreciated.

@ jdb

Thank you for your elegant solution. However, when I copy and paste your code and run it I am getting an error (see below). Could you help me understand why?

> library(dplyr)
> library(ggplot2)
> library(ISLR)
> library(GGally)
> data(Smarket)
> 
> Smarket$Class <- ifelse(Smarket$Direction == "Up", 1, -1)
> Smarket$Class <- as.factor(Smarket$Class)
> 
> ggpairs(Smarket %>% select(-9), aes(colour = Class, alpha = 0.4))
Error in FUN(X[[i]], ...) : 
  only defined on a data frame with all numeric variables
In addition: Warning message:
`panel.margin` is deprecated. Please use `panel.spacing` property instead 

@ jdb

Thank you again. I removed GGally and reinstalled it using the latest binary file from CRAN. Then it worked.


Solution

  • You can add the standard ggplot aesthetics with ggpairs, so converting the Class variable to a factor and using the colour aesthetic should do the trick.

    library(dplyr)
    library(ggplot2)
    library(ISLR)
    library(GGally)
    data(Smarket)
    
    Smarket$Class <- ifelse(Smarket$Direction == "Up", 1, -1)
    Smarket$Class <- as.factor(Smarket$Class)
    
    ggpairs(Smarket %>% select(-9), aes(colour = Class, alpha = 0.4))
    

    enter image description here