【问题标题】:How to name sections on x axis that are separated by vertical lines in an R plot (package ggplot2)?如何在 R 图中命名由垂直线分隔的 x 轴部分(包 ggplot2)?
【发布时间】:2012-08-25 03:51:46
【问题描述】:

我用 ggplot2 创建了一个堆积面积图,并在x-axis 的某些位置添加了垂直线。

我现在想命名由这些垂直线分隔的部分。它的一个示例可能看起来像示例图中所示。也欢迎其他解决方案。 我有一个breaks (x-axis) 的向量和一个间隔名称的向量。

代码:

library(ggplot2)
d <- read.delim(...)
x_breaks = c(-3999,1,599,4076,7557,11556)

png(output, width=800, height=400)

ggplot(d, aes(x=p, y=c, group=Groups, fill=Groups)) +
geom_area(position="stack") +
opts(title="testtestest",
...) +
scale_x_continuous(expand=c(0,0), breaks=x_breaks) +
scale_y_continuous(expand=c(0,0)) +
geom_vline(xintercept=x_breaks[which(x_breaks != min(x_breaks) & x_breaks != max(x_breaks))])

dev.off()

【问题讨论】:

    标签: r ggplot2 stacked-area-chart


    【解决方案1】:

    没有数据,重现您的示例(您的休息等)有点困难。但以下内容应该可以帮助您入门。

    一个相当简单的解决方案是使用 ggplot2 的 annotate() 函数将文本注释添加到垂直线之间的绘图面板中。

    # Load packages
    library (ggplot2)
    library(grid)
    
    # Some data
    df = data.frame(x = 1:10, y = 1:10)
    
    # Base plot
    p <- ggplot(df, aes(x,y)) + geom_point() + 
      scale_x_continuous(limits = c(0, 11), expand = c(0,0)) +
      geom_vline(xintercept = 3) + geom_vline(xintercept = 7)
    
    # Add the annotations
    p + annotate("text", x = .5*(0+3), y = 11, label = "Part 1") +
         annotate("text", x = .5*(3+7), y = 11, label = "Part 2") +
         annotate("text", x = .5*(7+11), y = 11, label = "Part 3")
    

    结果是:

    或者就注释而言,接近您的示例图的解决方案。它使用annotation_custom() 来绘制线条并将文本放置在绘图面板之外。即使注释是在绘图面板之外绘制的,注释的位置也是根据数据坐标进行的。基础图中的底部边距被加宽,以便为注释留出空间。该解决方案需要代码来覆盖 ggplot 将绘图元素剪辑到绘图面板。

    更新 opts 已弃用;改用theme。

    # Base plot
    p <- ggplot(df, aes(x,y)) + geom_point() + 
      scale_x_continuous(limits = c(0, 11), expand = c(0,0)) +
      geom_vline(xintercept = 3) + geom_vline(xintercept = 7) +
      theme(plot.margin = unit(c(1,1,4,1), "lines"))
    
    # Create the text Grobs
    Text1 = textGrob("Part 1")
    Text2 = textGrob("Part 2")
    Text3 = textGrob("Part 3")
    
    # Add the annotations
    # Segment 1
    p1 = p + 
        annotation_custom(grob = linesGrob(), xmin = 0, xmax = 0, ymin = -1, ymax = -.75) +
        annotation_custom(grob = linesGrob(), xmin = 0, xmax = 3, ymin = -1, ymax = -1) +
        annotation_custom(grob = linesGrob(), xmin = 3, xmax = 3, ymin = -1, ymax = -.75) +
        annotation_custom(grob = Text1,  xmin = 0, xmax = 3, ymin = -1.25, ymax = -1.25)
    
    # Segment 2
    p1 = p1 + 
        annotation_custom(grob = linesGrob(), xmin = 3, xmax = 7, ymin = -1, ymax = -1) +
        annotation_custom(grob = linesGrob(), xmin = 7, xmax = 7, ymin = -1, ymax = -.75) +
        annotation_custom(grob = Text2,   xmin = 3, xmax = 7, ymin = -1.25, ymax = -1.25) 
    
    # Segment 3
    p1 = p1 + 
        annotation_custom(grob = linesGrob(), xmin = 7, xmax = 11, ymin = -1, ymax = -1) +
        annotation_custom(grob = linesGrob(), xmin = 11, xmax = 11, ymin = -1, ymax = -.75) +
        annotation_custom(grob = Text3,  xmin = 7, xmax = 11, ymin = -1.25, ymax = -1.25)
    
    # Code to override clipping
    gt <- ggplot_gtable(ggplot_build(p1))
    gt$layout$clip[gt$layout$name=="panel"] <- "off"
    grid.draw(gt)
    

    结果是:

    【讨论】:

    • 这正是我想要的,非常感谢。我采用了您的第二个解决方案。我想让annotation_custom 的 y 位置取决于绘图的ylim (0.25*(top_ylim - bottom_ylim))。 你知道我怎样才能得到 y 限制吗?
    • 如果我理解正确:可以使用基本 R 函数 max() 和 min() 获得最大值和最小值。
    猜你喜欢
    • 2017-02-11
    • 1970-01-01
    • 2021-01-13
    • 1970-01-01
    • 1970-01-01
    • 2014-05-04
    • 2020-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多