代码之家  ›  专栏  ›  技术社区  ›  Dan

ggplot:切面之间的剪裁线

  •  1
  • Dan  · 技术社区  · 7 年前

    假设我有这样一个情节:

    # Load libraries
    library(ggplot2)
    library(grid)
    
    # Load data
    data(mtcars)
    
    # Plot results
    p <- ggplot(data = mtcars) 
    p <- p + geom_bar(aes(cyl)) 
    p <- p + coord_flip()
    p <- p + facet_wrap(~am)
    
    print(p)
    

    enter image description here

    现在,我想在横条所在的两个面上绘制直线。我补充说:

    p <- p + geom_vline(aes(xintercept = cyl))
    

    enter image description here

    # Turn off clipping
    gt <- ggplot_gtable(ggplot_build(p))
    gt$layout$clip[gt$layout$name == "panel"] <- "off"
    
    # Plot results
    grid.draw(gt)
    

    geom_vline 并尝试了 geom_abline geom_line (后者的值跨±Inf),但结果相同。在其他帖子中,剪裁解决方案似乎适用于文本和点,但在这种情况下,线可能仅在图形的限制范围内定义。(我甚至尝试过。) gt$layout$clip <- "off" 关闭所有可能的剪辑,但这并没有解决问题。)有解决方法吗?

    1 回复  |  直到 7 年前
        1
  •  0
  •   user20650    7 年前
    library(grid)
    library(gtable)
    
    # Starting from your plot `p`
    gb <- ggplot_build(p)
    g <- ggplot_gtable(gb)
    
    # Get position of y-axis tick marks
    ys <- gb$layout$panel_ranges[[1]][["y.major"]]
    
    
    # Add segments at these positions
    # subset `ys` if you only want to add a few
    # have a look at g$layout for relevant `l` and `r` positions
    g <- gtable_add_grob(g, segmentsGrob(y0=ys, y1=ys, 
                                         gp=gpar(col="red", lty="dashed")), 
                         t = 7, l = 4, r=8)
    
    grid.newpage()
    grid.draw(g)
    

    看见 ggplot, drawing multiple lines across facets 了解如何重新缩放值以进行更一般的打印。ie

    data2npc <- function(x, panel = 1L, axis = "x") {
      range <- pb$layout$panel_ranges[[panel]][[paste0(axis,".range")]]
      scales::rescale(c(range, x), c(0,1))[-c(1,2)]
    }
    
    start <- sapply(c(4,6,8), data2npc, panel=1, axis="y")
    
    g <- gtable_add_grob(g, segmentsGrob(y0=start, y1=start),
                          t=7, r=4, l=8)