Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set same scales across different facets with ggpairs()

Tags:

r

ggplot2

ggally

I have the following dataset and codes to construct the 2d density contour plot for each pair of variables in the data frame. My question is whether there is a way in ggpairs() to make sure that the scales are the same for different pairs of variables like the same scale for different facets in ggplot2. For example, I would like the x scale and y scale are all from [-1, 1] for each of the picture.

Thanks in advance!

The plot looks like enter image description here

library(GGally)
ggpairs(df,upper = list(continuous = "density"),
     lower = list(combo = "facetdensity"))

#the dataset looks like 
print(df)
         x           y           z             w
1   0.49916998 -0.07439680  0.37731097  0.0927331640
2   0.25281542 -1.35130718  1.02680343  0.8462638556
3   0.50950876 -0.22157249 -0.71134553 -0.6137126948
4   0.28740609 -0.17460743 -0.62504812 -0.7658094835
5   0.28220492 -0.47080289 -0.33799637 -0.7032576540
6  -0.06108038 -0.49756810  0.49099505  0.5606988283
7   0.29427440 -1.14998030  0.89409384  0.5656682378
8  -0.37378096 -1.37798177  1.22424964  1.0976507702
9   0.24306941 -0.41519951  0.17502049 -0.1261603208
10  0.45686871 -0.08291032  0.75929106  0.7457002259
11 -0.16567173 -1.16855088  0.59439600  0.6410396945
12  0.22274809 -0.19632766  0.27193362  0.5532901113
13  1.25555629  0.24633499 -0.39836999 -0.5945792966
14  1.30440121  0.05595755  1.04363679  0.7379212885
15 -0.53739075 -0.01977930  0.22634275  0.4699563173
16  0.17740551 -0.56039760 -0.03278126 -0.0002523205
17  1.02873716  0.05929581 -0.74931661 -0.8830775310
18 -0.13417946 -0.60421101 -0.24532606 -0.1951831558
19  0.11552305 -0.14462104  0.28545703 -0.2527437818
20  0.71783902 -0.12285529  1.23488185  1.3224880574
like image 262
Crystal Avatar asked Jun 08 '15 23:06

Crystal


2 Answers

I found a way to do this within ggpairs which uses a custom function to create the graphs

df <- read.table("test.txt")

upperfun <- function(data,mapping){
  ggplot(data = data, mapping = mapping)+
    geom_density2d()+
    scale_x_continuous(limits = c(-1.5,1.5))+
    scale_y_continuous(limits = c(-1.5,1.5))
}   

lowerfun <- function(data,mapping){
  ggplot(data = data, mapping = mapping)+
    geom_point()+
    scale_x_continuous(limits = c(-1.5,1.5))+
    scale_y_continuous(limits = c(-1.5,1.5))
}  


ggpairs(df,upper = list(continuous = wrap(upperfun)),
        lower = list(continuous = wrap(lowerfun)))      # Note: lower = continuous

With this kind of function it is as customizable as any ggplot!

Graph

like image 77
see24 Avatar answered Sep 22 '22 21:09

see24


Based on the answer from @see24, I noticed that the x-axis of the diagonal density plots is off. This can be mitigated in two different ways:

  1. by additionally defining a function diagfun for the diagonal elements of the ggpairs output.
  2. in case one doesn't care too much about the vertical axis of the density plots, one can simply add scale_x_continuous(...) and scale_y_continuous(limits = c(-1.5,1.5)) globally to the ggpairs() output.

Method 1

library(GGally)
#> Loading required package: ggplot2
#> Registered S3 method overwritten by 'GGally':
#>   method from   
#>   +.gg   ggplot2
df <- read.table(text = 
"         x           y           z             w
1   0.49916998 -0.07439680  0.37731097  0.0927331640
2   0.25281542 -1.35130718  1.02680343  0.8462638556
3   0.50950876 -0.22157249 -0.71134553 -0.6137126948
4   0.28740609 -0.17460743 -0.62504812 -0.7658094835
5   0.28220492 -0.47080289 -0.33799637 -0.7032576540
6  -0.06108038 -0.49756810  0.49099505  0.5606988283
7   0.29427440 -1.14998030  0.89409384  0.5656682378
8  -0.37378096 -1.37798177  1.22424964  1.0976507702
9   0.24306941 -0.41519951  0.17502049 -0.1261603208
10  0.45686871 -0.08291032  0.75929106  0.7457002259
11 -0.16567173 -1.16855088  0.59439600  0.6410396945
12  0.22274809 -0.19632766  0.27193362  0.5532901113
13  1.25555629  0.24633499 -0.39836999 -0.5945792966
14  1.30440121  0.05595755  1.04363679  0.7379212885
15 -0.53739075 -0.01977930  0.22634275  0.4699563173
16  0.17740551 -0.56039760 -0.03278126 -0.0002523205
17  1.02873716  0.05929581 -0.74931661 -0.8830775310
18 -0.13417946 -0.60421101 -0.24532606 -0.1951831558
19  0.11552305 -0.14462104  0.28545703 -0.2527437818
20  0.71783902 -0.12285529  1.23488185  1.3224880574")

upperfun <- function(data,mapping){
  ggplot(data = data, mapping = mapping)+
    geom_density2d()+
    scale_x_continuous(limits = c(-1.5,1.5))+
    scale_y_continuous(limits = c(-1.5,1.5))
}   
lowerfun <- function(data,mapping){
  ggplot(data = data, mapping = mapping)+
    geom_point()+
    scale_x_continuous(limits = c(-1.5,1.5))+
    scale_y_continuous(limits = c(-1.5,1.5))
}  
diagfun <- function (data, mapping, ..., rescale = FALSE){
  # code based on GGally::ggally_densityDiag
  mapping <- mapping_color_to_fill(mapping)
  p <- ggplot(data, mapping) + scale_y_continuous()
  if (identical(rescale, TRUE)) {
    p <- p + stat_density(aes(y = ..scaled.. * 
                                diff(range(x,na.rm = TRUE)) +
                                min(x, na.rm = TRUE)), 
                          position = "identity", 
                          geom = "line", 
                          ...)
  } else {
    p <- p + geom_density(...)
  }
  p +
    scale_x_continuous(limits = c(-1.5,1.5)) #+
    # scale_y_continuous(limits = c(-1.5,1.5))
}
ggpairs(df,
        upper = list(continuous = wrap(upperfun)),
        diag = list(continuous = wrap(diagfun)),        # Note: lower = continuous
        lower = list(continuous = wrap(lowerfun)))      # Note: lower = continuous

Created on 2022-01-13 by the reprex package (v2.0.1)

Method 2

  library(GGally)
#> Loading required package: ggplot2
#> Registered S3 method overwritten by 'GGally':
#>   method from   
#>   +.gg   ggplot2
  df <- read.table(text = 
                     "         x           y           z             w
1   0.49916998 -0.07439680  0.37731097  0.0927331640
2   0.25281542 -1.35130718  1.02680343  0.8462638556
3   0.50950876 -0.22157249 -0.71134553 -0.6137126948
4   0.28740609 -0.17460743 -0.62504812 -0.7658094835
5   0.28220492 -0.47080289 -0.33799637 -0.7032576540
6  -0.06108038 -0.49756810  0.49099505  0.5606988283
7   0.29427440 -1.14998030  0.89409384  0.5656682378
8  -0.37378096 -1.37798177  1.22424964  1.0976507702
9   0.24306941 -0.41519951  0.17502049 -0.1261603208
10  0.45686871 -0.08291032  0.75929106  0.7457002259
11 -0.16567173 -1.16855088  0.59439600  0.6410396945
12  0.22274809 -0.19632766  0.27193362  0.5532901113
13  1.25555629  0.24633499 -0.39836999 -0.5945792966
14  1.30440121  0.05595755  1.04363679  0.7379212885
15 -0.53739075 -0.01977930  0.22634275  0.4699563173
16  0.17740551 -0.56039760 -0.03278126 -0.0002523205
17  1.02873716  0.05929581 -0.74931661 -0.8830775310
18 -0.13417946 -0.60421101 -0.24532606 -0.1951831558
19  0.11552305 -0.14462104  0.28545703 -0.2527437818
20  0.71783902 -0.12285529  1.23488185  1.3224880574")
  ggpairs(df,
          upper = list(continuous = "density"),
          lower = list(combo = "facetdensity")) +
    scale_x_continuous(limits = c(-1.5,1.5)) +
    scale_y_continuous(limits = c(-1.5,1.5))
#> Scale for 'y' is already present. Adding another scale for 'y', which will
#> replace the existing scale.
#> Scale for 'y' is already present. Adding another scale for 'y', which will
#> replace the existing scale.
#> Scale for 'y' is already present. Adding another scale for 'y', which will
#> replace the existing scale.
#> Scale for 'y' is already present. Adding another scale for 'y', which will
#> replace the existing scale.

Created on 2022-01-13 by the reprex package (v2.0.1)

like image 20
fabern Avatar answered Sep 19 '22 21:09

fabern