rggpairs

R ggpairs change the colour of bar histograms on diagonal


I would like to change the colour of the bars of the histogram on a pairs plot whereby I have a different colour for each variable. It appears I can change the colour of ALL diagonal histograms by changing the 'fill =' option to a new colour but when I attempt to substitute a list of four colours I get the error report:

"r: Aesthetics must be either length 1 or the same as the data (15): fill"

So it seems the colours are somehow linked to the number of bins specified for the histograms not the fill colour for each histogram?

What is the best way to achieve a different colour for each histogram on the diagonal?

Example code below:

require(GGally)

# function for scatter plots with smoothed trend line
lower_plots <- function(data, mapping, ...) {
  ggplot(data = data, mapping = mapping) +
    geom_point(color = "black", shape = 1, size = 1, alpha = 1) +
    geom_smooth(method = "gam",...) 
} 

# colour palette for histograms - subsitue for fill = ?
clrs <- c("red","green","blue","orange")

# pairs plot
ggpairs(iris,1:4, 
        diag = list(continuous = wrap("barDiag", bins = 15, fill = "blue")),
        lower = list(continuous = wrap(lower_plots, color="red", se=F))) +
  theme_light(base_size = 12) +                                                                                                                 
  theme_light(base_size = 12) +                                                                                                                 
  scale_fill_manual(values = ZNS[order(ZNS$Zone), 4])  +                                                                                         
  theme(panel.grid.minor = element_blank(), panel.grid.major = element_blank()) +
  theme(plot.margin = unit(c(2.5,2.5,2.5,3.5), "lines")
  ) 

enter image description here


Solution

  • I found a work arround for your problem by using global assignment from inside of a function. First I though it was not possible due to the lack of beeing able to identify in one column of the input how to color the histograms, as each line contains multiple observations... I tested a bit and wondered, that given the fact of everything beeing processed in batches/loops, global assignment would help - and it does:

    require(GGally)
    
    # function for scatter plots with smoothed trend line
    lower_plots <- function(data, mapping, ...) {
        ggplot(data = data, mapping = mapping) +
            geom_point(color = "black", shape = 1, size = 1, alpha = 1) +
            geom_smooth(method = "gam",...) 
    } 
    
    # working with a trick of global assignment
    diag_plots <- function(data, mapping, ...) {
        # increase counter each run globally so outside the function as well and this does the trick!
        x <<- x + 1
        ggplot(data = data, mapping = mapping) +
            # choose color by counter and send bin width argument in
            geom_histogram(fill = clrs[x], ...)
    } 
    
    # set the color and counter
    clrs <- c("red","green","blue","orange")
    x <- 0
    
    # pairs plot
    ggpairs(iris,1:4, 
            diag = list(continuous = wrap(diag_plots, bins = 15)),
            lower = list(continuous = wrap(lower_plots, color="red", se=FALSE))) +
            theme_light(base_size = 12) + 
            theme_light(base_size = 12) + 
            theme(panel.grid.minor = element_blank(), panel.grid.major = element_blank()) +
        theme(plot.margin = unit(c(2.5,2.5,2.5,3.5), "lines")) 
    

    enter image description here