【问题标题】:How to set same scales across different facets with ggpairs()如何使用 ggpairs() 在不同方面设置相同的比例
【发布时间】:2015-06-08 23:01:26
【问题描述】:

我有以下数据集和代码来为数据框中的每对变量构建二维密度等高线图。我的问题是 ggpairs() 中是否有办法确保不同变量对的尺度相同,例如 ggplot2 中不同方面的尺度相同。例如,我希望每张图片的 x 比例和 y 比例都来自 [-1, 1]。

提前致谢!

情节看起来像

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

【问题讨论】:

    标签: r ggplot2 ggally


    【解决方案1】:

    我在ggpairs 中找到了一种方法,它使用自定义函数来创建图表

    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
    

    有了这种功能,它就像任何 ggplot 一样可定制!

    【讨论】:

    • 我认为这应该是现在公认的答案,因为它更通用,并且直接在ggpairs() 内提供了解决方案。
    • 请注意,与其他解决方案一样,密度图的 x 尺度与下对角线不一致。
    • 要修复对角线的 x 比例,您可以采用类似的方法,根据 GGally::ggally_densityDiag 的源代码创建函数 diagfun 并在其中添加 scale_x_continuous(limits = c(-1.5,1.5))。然后另外使用ggparis(diag = )
    • 另一种固定对角线 x 比例的方法是在 plotmatrix 创建后对其进行修改:ggpairs() + scale_x_continuous(limits = c(-1.5,1.5))。实际上,如果不太关心密度图的 y 轴,整个问题都可以通过 ggpairs() + scale_x_continuous(limits = c(-1.5,1.5)) + scale_y_continuous(limits = c(-1.5,1.5)) 解决。
    • @see24,我刚刚发布了另一个关于该方法的 MWE 答案。
    【解决方案2】:

    我不确定这是否可以直接从 ggpairs 函数中实现,但您可以从 ggpairs 中提取图并对其进行修改,然后将其保存回来。

    此示例循环遍历绘图矩阵的下三角形并替换现有的 x 和 y 轴刻度。

    data(tips, package = "reshape")
    ## pm is the original ggpair object
    pm <- ggpairs(tips[,c("total_bill", "tip", "size")])
    ## pm2 will be modified in the loop
    pm2 <- pm
    for(i in 2:pm$nrow) {
      for(j in 1:(i-1)) {
        pm2[i,j] <- pm[i,j] +
          scale_x_continuous(limits = c(-5, 75)) +
          scale_y_continuous(limits = c(-5, 10))
    }
    }
    

    pm 看起来像这样

    pm2 看起来像这样

    要解决您的问题,您需要遍历整个绘图矩阵并将 x 和 y 比例设置为 -1 到 1 的范围。

    编辑:请注意,密度不变,因为它们仍处于原始比例,因此在手动修改某些绘图的方法时要非常小心,因为结果可能会产生误导。我更喜欢在 ggpairs 中使用自定义函数的替代方法。

    【讨论】:

      【解决方案3】:

      根据@see24 的回答,我注意到对角线密度图的 x 轴已关闭。这可以通过两种不同的方式来缓解:

      1. ggpairs 输出的对角线元素额外定义一个函数diagfun
      2. 如果不太关心密度图的垂直轴,可以简单地将scale_x_continuous(...)scale_y_continuous(limits = c(-1.5,1.5)) 全局添加到ggpairs() 输出中。

      方法一

      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
      

      reprex package (v2.0.1) 于 2022-01-13 创建

      方法二

        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.
      

      reprex package (v2.0.1) 于 2022-01-13 创建

      【讨论】:

      • 方法2很棒!简单多了!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-02-06
      • 1970-01-01
      • 2014-01-02
      • 2020-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多