washfaq
washfaq

Reputation: 322

How to customize graph with 2nd correlation line in ggpairs

Following the post, How to customize lines in ggpairs [GGally] I have made graphenter image description here by using below code;

library("GGally")
library("ggplot2")
data(iris)

lowerFn <- function(data, mapping, method = "lm", ...) {
  p <- ggplot(data = data, mapping = mapping) +
    geom_point(colour = "blue") +
    geom_smooth(method = method, color = "red", ...)
  p
}

ggpairs(
  iris[, 1:4], lower = list(continuous = wrap(lowerFn, method = "lm")),
  diag = list(continuous = wrap("barDiag", colour = "blue")),
  upper = list(continuous = wrap("cor", size = 10))
)

My question is;

  1. How can I made a same style scatter plot matrices graph by adding "Sil" variable effect as correlation lines on graph. Like this graph showing Si variable effect as 2 correlation lines enter image description here

data is here, (iris data with added Sil variable) https://docs.google.com/spreadsheets/d/15voAmJ7vcozmHYKYnHxFd_3A3fkkIvzQV6zi44lIEGg/edit#gid=0

Upvotes: 1

Views: 1570

Answers (1)

user20650
user20650

Reputation: 25874

If you want to colour the points and produce a regression fitted line by group then you need to map the aesthetics to some variable.

In the general case you can add the mapping to the top level, and this will split all the panels by group.

ggpairs(iris, columns=1:4, mapping=aes(colour=Species))

However, I think you need to do a little more work if you only want to plot by group in one section of the panel. One way is to first change your user function to the following, This provides an additional emap parameter that will control the aesthetics in lowerFn only.

lowerFn <- function(data, mapping, emap=NULL, method = "lm", ...) {
  # mapping <- c(mapping, emap)
  # class(mapping) = "uneval" # need this to combine the two aes
  # Can use this instead
  mapping <- ggplot2:::new_aes( c(mapping, emap))
  p <- ggplot(data = data, mapping = mapping) +
    geom_point() +
    geom_smooth(method = method, ...) +
    theme_classic() # to get the white background and prominent axis
  p
}

You can then call it with the following, which should leave the diagonal and upper aesthetics alone.

ggpairs(
  iris, columns=1:4,
  lower = list(continuous = wrap(lowerFn, 
                                 method = "lm", fullrange=TRUE, se=FALSE,
                                 emap=aes(color=Species))))                             

This produces

enter image description here

You could of course just hard code your grouping variable into the user function:

lowerFn <- function(data, mapping, method = "lm", ...) {
  p <- ggplot(data = data, mapping = mapping) +
    geom_point(aes(colour=Species)) +
    geom_smooth(method = method, aes(colour=Species), ...)
  p
}

ggpairs(
  iris, columns=1:4,
  lower = list(continuous = 
                 wrap(lowerFn, method = "lm", 
                      fullrange=TRUE, se=FALSE)))

Comment: when you add the colour parameter to geom_point or geom_smooth in your user function it will overrule a mapped colour e.g. compare the results from the following

ggplot(iris, aes(Sepal.Length, Sepal.Width, col=Species)) +
  geom_smooth(se=FALSE)

ggplot(iris, aes(Sepal.Length, Sepal.Width, col=Species)) +
  geom_smooth(col="red", se=FALSE)

Q? How can I enter key for regression line on the graph?

If you were using a global / top-level aesthetic you could use ggpairs(iris, columns=1:4, aes(colour=Species), legend=1) and normal ggplot theme functions to control it. This cannot be done here as the grouping variable was used in a custom function. However, the package provides a means to add custom legends with the legend argument; you can generate a dummy legend outside of ggpairs and then add it in during the plotting.

leg <- grab_legend(ggplot(data=iris, aes(x=NA, y=NA, colour=Species)) +
              geom_line() + theme(legend.direction = "horizontal"))

ggpairs(
  iris, columns=1:4, legend=leg,
  lower = list(continuous = 
                 wrap(lowerFn, method = "lm", 
                      emap=aes(color=Species),
                      fullrange=TRUE, se=FALSE))) +
  theme(legend.position = "top")

Upvotes: 4

Related Questions