【问题标题】:Remove unnecessary y-axis points with facet_wrap and geom_segment使用 facet_wrap 和 geom_segment 删除不必要的 y 轴点
【发布时间】:2017-08-20 11:51:46
【问题描述】:

我使用geom_segment() 将y 轴点映射到x 轴,然后使用facet_wrap 将数据分成两个图;但是,两个图上都显示了 y 轴点。

我怎样才能只有与每个 facet_wrap 相关的必要 y 轴点?

示例代码

dat <- structure(list(temp = c(1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 
4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5), rev = c(-5, 
-11, -20, -29, -40, -9, -20, -32, -45, -57, -12, -24, -37, -50, 
-62, -7, -20, -36, -52, -67, -5, -13, -23, -35, -47, -12, -24, 
-36, -48, -58), type = c("Type 1", "Type 1", "Type 1", "Type 1", 
"Type 1", "Type 1", "Type 1", "Type 1", "Type 1", "Type 1", "Type 1", 
"Type 1", "Type 1", "Type 1", "Type 1", "Type 2", "Type 2", "Type 2", 
"Type 2", "Type 2", "Type 2", "Type 2", "Type 2", "Type 2", "Type 2", 
"Type 2", "Type 2", "Type 2", "Type 2", "Type 2"), model = c("A", 
"A", "A", "A", "A", "B", "B", "B", "B", "B", "C", "C", "C", "C", 
"C", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "C", "C", 
"C", "C", "C")), .Names = c("temp", "rev", "type", "model"), row.names = c(NA, 
-30L), class = "data.frame")

p1 <- ggplot(dat, aes(temp, rev, color = model)) + 
  geom_line() + geom_point() + geom_segment(aes(x = 0, xend = temp, yend = rev), linetype = "dashed", color = "grey") + 
  facet_wrap(~type, scales = "free") + scale_y_continuous(breaks = dat$rev)
p1

情节

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    我编造了虚拟数据,因为出于某种原因将您的 dput 粘贴到我的控制台中会让人不高兴。

    library(dplyr)
    
    df <- expand.grid(temp = 1:5, model = LETTERS[1:3], type = 1:2) %>% 
      group_by(model, type) %>% 
      mutate(rev = -sort(sample.int(20, length(temp)))) 
    
    # this is equivalent to your data as-is, structurewise
    

    df.labeled <- df %>% 
      ungroup() %>% group_by(type, rev) %>% 
      mutate(label = c(rev[1], rep(NA, length(rev) - 1)))
    

    在这里,我为每个组面板中显示的每个 y 值创建了一个组。然后我创建一个label 列,其中包含对该y 值的1 个观察值,并用NAs 填充。因此,如果一个面板有两个模型,每个模型都有一个 rev-5,那么现在它将是 -5, NA 而不是 -5, -5。为什么我这样做会在下面变得更清楚。


    ggplot(df.labeled, aes(temp, rev, color = model)) + 
      geom_segment(aes(xend = 0, yend = rev), linetype = "dashed", color = "grey") +
      geom_text(aes(label = label, x = -0.1), colour = "black", hjust = 1) +
      geom_vline(xintercept = 0) +
      geom_point() + geom_line() + facet_grid(~type) + 
      scale_y_continuous(breaks = NULL) + 
      scale_x_continuous(limits = c(-0.5, NA)) +
      theme_bw() + theme(panel.grid = element_blank())
    

    如果我留下了重复项(此处为 -7,类型 1 为 -15,类型 2 为 -11),geom_text 将是一个凌乱的粗体模糊。重复的文本标签在 ggplot2 中呈现不佳。由于实际上不可能按照您想要的方式进行操作,因此我们只是为每个面板制作了一个假秤。如果您不喜欢数字左侧的 y 轴上有一条额外的线,可以去掉:

      ... + 
      theme(panel.grid = element_blank(),
            panel.border = element_blank(),
            axis.line.x = element_line())
    

    【讨论】:

    • 很好的答案。谢谢!
    • 这很好用,除非我添加更多模型。然后我会在 y 轴标签上聚集在一起,从而使它们难以阅读。有没有办法使用这种方法,但将y轴展开以防止标签重叠?
    • 如果有那么多点,也许常规的未修改的 y 轴是最好的 ;) 你总是可以尝试使用更高的纵横比:ggsave("file.png", width = 6, height = 8)。您也可以尝试使用 ggrepel 包来微调标签。
    【解决方案2】:

    我们可以通过type分割数据框,创建分离图,然后使用gridExtra包中的grid.arrange组合两个图。

    library(ggplot2)
    library(gridExtra)
    
    # Split the data
    dat_list <- split(dat, dat$type)
    
    # Use lapply to create plot for both subset
    p_list <- lapply(dat_list, function(x){
    
      p1 <- ggplot(x, aes(temp, rev, color = model)) + 
        geom_line() + 
        geom_point() + 
        geom_segment(aes(x = 0, xend = temp, yend = rev), linetype = "dashed", color = "grey") + 
        scale_y_continuous(breaks = x$rev) +
        facet_wrap(~type, scales = "free")
      return(p1)
    })
    
    # Plot the data
    grid.arrange(grobs = p_list, nrow = 1)
    

    更新

    另一种选择是使用cowplot 包。这似乎是一种创造共同传奇的方式。

    library(cowplot)
    
    # Get the common legend, p_list is from the previous example
    legend_both <- get_legend(p_list[[1]])
    
    # Plot the plots and the common legend together
    # Use rel_widths to set the column width
    plot_grid(p_list[[1]] + theme(legend.position = "none"),
              p_list[[2]] + theme(legend.position = "none"),
              legend_both, 
              nrow = 1,
              rel_widths = c(2, 2, 1))
    

    【讨论】:

    • 这是我的第一个想法,但我希望有一种方法可以将其保存在 ggplot 中,而无需拆分数据。这样,y 轴将排列以显示模型和类型之间的关系。不过还是谢谢。
    • 我知道。最好只使用ggplot2。我仍在寻找可能的方法来做到这一点。希望其他人可以分享他们的想法。
    • 要保持坐标轴对齐,您可以使用cbind.gtablegrid.arrange 的组合,但也有一个hack 解决方法...
    • 我通常使用cowplot 进行多图,所以这当然也是一个选项。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-02
    • 2019-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多