Search code examples
rggplot2ggpairs

Ggpairs barDiag with normal curve


I am using the ggpairs from ggplot2.

I need to get an histogram in the diagonal for the ggpairs, but want to superimpose the normal density curve using the mean and sd of the data.

I read the help (https://www.rdocumentation.org/packages/GGally/versions/1.4.0/topics/ggpairs) but can't find an option to do it. I guess I must built my own function (myfunct) and then

ggpairs(sample.dat, diag=list(continuous = myfunct))

Has anyone have tried this?


I have tried the following:

head(data) 
      x1    x2    x3    x4    x5    x6     F1    F2 
1 -0.749 -1.57 0.408 0.961 0.777 0.171 -0.143 0.345 

myhist = function(data){ 
          ggplot(data, aes(x)) + 
             geom_histogram(aes(y = ..density..),colour = "black") + 
             stat_function(fun = dnorm, args = list(mean = mean(x), sd = sd(x))) 
           } 

ggpairs(sample.data, diag=list(continuous = myhist))

The result is:

Error in (function (data) : unused argument (mapping = list(~x1))


Solution

  • This question provides an example of the code to add a normal curve to a histogram in ggplot2. You can use this to write your own function to pass to the diag argument of ggpairs. To calculate the mean and sd of the data, you can grab the relevant data using, for example, eval_data_col(data, mapping$x). Example below (perhaps a little more complicated than needed but it allows you to pass parameters to change colours etc using the wrap functionality.

    library(GGally)    
    
    diag_fun <- function(data, mapping, hist=list(), ...){
    
        X = eval_data_col(data, mapping$x)
        mn = mean(X)
        s = sd(X)
    
        ggplot(data, mapping) + 
          do.call(function(...) geom_histogram(aes(y =..density..), ...), hist) +
          stat_function(fun = dnorm, args = list(mean = mn, sd = s), ...)
      }
    
    ggpairs(iris[1:100, 1:4], 
            diag=list(continuous=wrap(diag_fun, hist=list(fill="red", colour="blue"), 
                                      colour="green", lwd=2)))