代码之家  ›  专栏  ›  技术社区  ›  Dave Gruenewald

基于其他列的ggplot2刻面中的自定义轴打断

  •  1
  • Dave Gruenewald  · 技术社区  · 6 年前

    我有数据要绘制,其中x轴在一列中,x轴的主要断点在其他列中。

    对于我的示例数据,我将修改 iris 数据集来自 ggplot2 .注: low high 这里是任意计算的——我只选择了min&最大值,便于再现。

    library(dplyr)
    library(ggplot2)
    
    
    df <- iris %>% 
      group_by(Species) %>% 
      mutate(low = min(Sepal.Length),
             high = max(Sepal.Length)) %>% 
      ungroup()
    
    > df
    # A tibble: 150 x 7
       Sepal.Length Sepal.Width Petal.Length Petal.Width Species   low  high
              <dbl>       <dbl>        <dbl>       <dbl> <fct>   <dbl> <dbl>
     1          5.1         3.5          1.4         0.2 setosa    4.3   5.8
     2          4.9         3            1.4         0.2 setosa    4.3   5.8
     3          4.7         3.2          1.3         0.2 setosa    4.3   5.8
     4          4.6         3.1          1.5         0.2 setosa    4.3   5.8
     5          5           3.6          1.4         0.2 setosa    4.3   5.8
     6          5.4         3.9          1.7         0.4 setosa    4.3   5.8
     7          4.6         3.4          1.4         0.3 setosa    4.3   5.8
     8          5           3.4          1.5         0.2 setosa    4.3   5.8
     9          4.4         2.9          1.4         0.2 setosa    4.3   5.8
    10          4.9         3.1          1.5         0.1 setosa    4.3   5.8
    # ... with 140 more rows
    

    我希望策划 x = Sepal.Length 刻面 Species ,但只有两个主要突破 df$min df$max .

    我很难在正确的方面得到突破。

    df %>% 
      ggplot(aes(x = Sepal.Length,
                 y = Petal.Length)) + 
      geom_point() + 
      facet_wrap(. ~ Species) + 
      scale_x_continuous(breaks = c(df$low, df$high))
    

    enter image description here

    如您所见 df$low df$high 适用于所有方面。我希望这方面 setosa 仅在4.3和5.8处有重大突破, versicolor 仅在4.9和7.0处,以及 virginica 仅为4.9和7.9。

    是否有方法将方面变量传递给 breaks 在里面 scale_x_continuous 或者我应该放弃这种方法,创建三个单独的ggplots,并将它们合并在一起 gridExtra ?

    任何帮助都将不胜感激!

    0 回复  |  直到 6 年前
        1
  •  2
  •   dave-edison    6 年前

    以下是一个可能的解决方案,使用 patchwork :

    library(ggplot2)
    library(purrr)
    library(patchwork)
    
    df %>% 
      split(.$Species) %>% 
      map(~{
        .x %>% 
          ggplot(aes(x = Sepal.Length,
                     y = Petal.Length)) + 
            geom_point() + 
            facet_wrap(~ Species) + 
            scale_x_continuous(breaks = c(max(.x$low), max(.x$high))) +
            # assuming you want to use same y axis for each plot
            scale_y_continuous(limits = c(min(df$Petal.Length), max(df$Petal.Length)))
      }) %>% 
      reduce(`+`)
    

    enter image description here

    我认为这是最简单的方法,不涉及捣乱 ggproto

        2
  •  1
  •   teunbrand    6 年前

    scale的break参数不支持在传递给主ggplot2调用的data.frame上下文中进行整洁的计算。如果您的中断可以从方面限制(通常是数据限制+扩展,当 scales = "free" ),您可以向breaks参数传递一个函数,该函数计算超出限制的断点。

    如果你真的打算为每个方面设置单独的比例,github上有一些包支持为绘图的各个方面提供自定义比例。两者都要求您手动为每个方面指定比例。免责声明:我为第一个包做出了贡献,并且是第二个包的作者。

    library(dplyr)
    #> 
    #> Attaching package: 'dplyr'
    #> The following objects are masked from 'package:stats':
    #> 
    #>     filter, lag
    #> The following objects are masked from 'package:base':
    #> 
    #>     intersect, setdiff, setequal, union
    library(ggplot2)
    
    
    df <- iris %>% 
      group_by(Species) %>% 
      mutate(low = min(Sepal.Length),
             high = max(Sepal.Length)) %>% 
      ungroup()
    
    # Forgive the clunky tidyverse syntax
    scale_list <- df$Species %>% levels() %>% setNames(.,.) %>% lapply(., function(i) {
      scale_x_continuous(breaks = unique(unlist(df[df$Species == i, c("low", "high")])))
    })
    
    #devtools::install_github("zeehio/facetscales")
    library(facetscales)
    
    df %>% 
      ggplot(aes(x = Sepal.Length,
                 y = Petal.Length)) + 
      geom_point() + 
      facet_grid_sc(cols = vars(Species), scales = list(x = scale_list))
    

    
    #devtools::install_github("teunbrand/ggnomics")
    library(ggnomics)
    
    df %>% 
      ggplot(aes(x = Sepal.Length,
                 y = Petal.Length)) + 
      geom_point() + 
      facet_wrap(. ~ Species, scales = "free_x") +
      facetted_pos_scales(x = scale_list)
    

    创建于2020年2月11日 reprex package (v0.3.0)

    推荐文章