【问题标题】:How to plot facets with discontinuous y-axis如何绘制具有不连续 y 轴的构面
【发布时间】:2021-05-21 20:22:00
【问题描述】:

我正在尝试生成一个 y 轴不连续的图,但无法让刻面标题只显示一次:

示例数据:

data(mpg)
library(ggplot2)
> ggplot(mpg, aes(displ, cty)) +
+     geom_point() +
+     facet_grid(. ~ drv)

经过大量挖掘,这似乎在ggplot2 中是不可能的,但我发现了gg.gap 包。然而,这个包复制了情节的每个部分的刻面标题。假设我想要 y 轴从 22-32 中断,如下所示:

library(gg.gap)
gg.gap(plot = p,
       segments = c(22, 32),
       ylim = c(0, 35))

每个情节片段都会出现构面标题,但这显然非常令人困惑且在美学上很糟糕。对于任何人可以提供的帮助,我将不胜感激!我被难住了。

我知道如果我在基础 R 中绘图,这是可能的,但考虑到其他限制,我无法这样做(我需要 ggplot2 提供的图形/语法。

提前致谢!

【问题讨论】:

    标签: r ggplot2 facet-grid yaxis


    【解决方案1】:

    这是一个有点丑陋的解决方法。想法是将损坏部分中的 y 值设置为NA,这样就不会在那里绘制任何点。然后,我们在findInterval() 上刻面,并带有轴的中断(否定,因为我们想保留从下到上的轴)。最后,我们使用ggh4x::force_panelsizes() 手动调整面板的大小,将第二个面板的高度设置为 0。完全免责声明,我写了 ggh4x,所以我有偏见。

    一些细节:通过将相关主题元素设置为空白来隐藏沿 y 方向的条带。此外,理想情况下,您应该计算上刻面与下刻面的比例,并将0.2 替换为该数字。

    library(ggplot2)
    library(ggh4x)
    
    ggplot(mpg, aes(displ, cty)) +
      geom_point(aes(y = ifelse(cty >= 22 & cty < 32, NA, cty))) +
      facet_grid(-findInterval(cty, c(-Inf, 22, 32, Inf)) ~ drv, 
                 scales = "free_y", space = "free_y") +
      theme(strip.background.y = element_blank(),
            strip.text.y = element_blank(),
            panel.spacing.y = unit(5.5/2, "pt")) +
      force_panelsizes(rows = c(0.2, 0, 1))
    #> Warning: Removed 20 rows containing missing values (geom_point).
    

    箱线图的替代方法:

    您可以复制数据并操纵位置比例来显示您想要的,而不是审查中断的位。我们依靠坐标系对数据的裁剪来裁剪图形对象。

    library(ggplot2)
    library(ggh4x)
    
    ggplot(mpg, aes(class, cty)) +
      geom_boxplot(data = ~ transform(., facet = 2)) +
      geom_boxplot(data = ~ transform(., facet = 1)) +
      facet_grid(facet ~ drv, scales = "free_y", space = "free_y") +
      facetted_pos_scales(y = list(
        scale_y_continuous(limits = c(32, NA), oob = scales::oob_keep, # <- keeps data
                           expand = c(0, 0, 0.05, 0)),
        scale_y_continuous(limits=  c(NA, 21), oob = scales::oob_keep,
                           expand = c(0.05, 0, 0, 0))
      )) +
      theme(strip.background.y = element_blank(),
            strip.text.y = element_blank())
    

    【讨论】:

    • 谢谢@teunbrand。考虑到未来的用途,有没有什么办法可以得到同样的结果,但又不将未表示的数据更改为NA?我在这里考虑条形图、线图或箱形图。将数据更改为NA 将在这些情况下导致问题。我在他的回答框架内向@JonSpring 提出了同样的问题。我可以看到每种解决方案的用途,但不确定如何将它们扩展到更广泛的地块。
    • 我已经使用适合箱线图的解决方案进行了编辑,尽管方法有点不同。
    • @teunbrand - 太棒了!但是,我收到一个错误 (Error: 'oob_keep' is not an exported object from 'namespace:scales')。即使我运行您在箱线图示例中的代码,也会出现此错误。我尝试更新我的 scales 包但没有运气。有什么想法吗?
    • 根据their news,我认为它应该在 v1.1.1 中。这是github上的函数,应该很容易复制。
    【解决方案2】:

    这是一种方法,它依赖于在 ggplot2 之前更改数据,然后调整比例标签,这与您对辅助 y 轴所做的操作相当。

    library(dplyr)
    low_max <- 22.5
    high_min <- 32.5
    adjust <- high_min - low_max
    
    mpg %>%
      mutate(cty2 = as.numeric(cty),
             cty2 = case_when(cty < low_max ~ cty2,
                             cty > high_min ~ cty2 - adjust,
                             TRUE ~ NA_real_)) %>%
    ggplot(aes(displ, cty2)) +
      geom_point() +
      annotate("segment", color = "white", size = 2,
           x = -Inf, xend = Inf, y = low_max, yend = low_max) +
      scale_y_continuous(breaks = 1:50, 
                         label = function(x) {x + ifelse(x>=low_max, adjust, 0)}) +
      facet_grid(. ~ drv)
    

    【讨论】:

    • 谢谢@jon!考虑到未来的用途,有没有什么方法可以得到同样的结果,但又不将未表示的数据更改为NA?我在这里考虑条形图、线图或箱形图。将数据更改为NA 将在这些情况下导致问题。我在他的回答框架内向@teunbrand 提出了同样的问题。我可以看到每种解决方案的用途,但不确定如何将它们扩展到更广泛的地块。
    猜你喜欢
    • 2013-10-04
    • 1970-01-01
    • 1970-01-01
    • 2021-05-17
    • 1970-01-01
    • 2016-09-26
    • 2019-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多