ggplot2 - 在剧情之外注释

jsl*_*che 62 annotations r ggplot2

我想将样本大小值与绘图上的点相关联.我可以geom_text用来定位点附近的数字,但这很麻烦.将它们沿着图的外边缘排列会更加清晰.

例如,我有:

df=data.frame(y=c("cat1","cat2","cat3"),x=c(12,10,14),n=c(5,15,20))

ggplot(df,aes(x=x,y=y,label=n))+geom_point()+geom_text(size=8,hjust=-0.5)
Run Code Online (Sandbox Code Playgroud)

这产生了这个情节: 在此输入图像描述

我更喜欢这样的东西: 在此输入图像描述

我知道我可以创建第二个图并使用grid.arrange(这篇文章),但确定textGrobs与y轴对齐的间距会很繁琐.有更简单的方法吗?谢谢!

San*_*att 56

你不需要绘制第二个图.您可以使用annotation_custom在绘图区域内部或外部的任何位置定位凹凸.凹槽的定位是根据数据坐标.假设"5","10","15"与"cat1","cat2","cat3"对齐,textGrobs的垂直位置被处理 - 你的三个textGrobs的y坐标由三个数据点的y坐标.默认情况下,ggplot2剪辑会缩放到绘图区域,但可以覆盖裁剪.需要扩大相关的保证金,以便为grob腾出空间.以下(使用ggplot2 0.9.2)给出了与第二个图类似的图:

library (ggplot2)
library(grid)

df=data.frame(y=c("cat1","cat2","cat3"),x=c(12,10,14),n=c(5,15,20))

p <- ggplot(df, aes(x,y)) + geom_point() +            # Base plot
     theme(plot.margin = unit(c(1,3,1,1), "lines"))   # Make room for the grob

for (i in 1:length(df$n))  {
p <- p + annotation_custom(
      grob = textGrob(label = df$n[i], hjust = 0, gp = gpar(cex = 1.5)),
      ymin = df$y[i],      # Vertical position of the textGrob
      ymax = df$y[i],
      xmin = 14.3,         # Note: The grobs are positioned outside the plot area
      xmax = 14.3)
 }    

# Code to override clipping
gt <- ggplot_gtable(ggplot_build(p))
gt$layout$clip[gt$layout$name == "panel"] <- "off"
grid.draw(gt)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • @jslefche,你应该注意到@baptiste提供的解决方案要简单得多.`p = p + geom_text(aes(label = n,x = Inf,y = y),hjust = -1)`.然后关闭剪辑.虽然对齐可能略有偏差. (13认同)
  • 在x = Inf,hjust> = 1时有一个geom_text图层并不容易,并关闭剪裁? (9认同)
  • 如何关闭剪裁? (2认同)
  • 不幸的是,您需要定位文本的x位置随x轴的范围而变化.因此,您需要使用相对于轴范围的x值.这是我的解决方案.我得到x ggplot计算轴范围与`xlim.range < - ggplot_build(plot)$ panel $ ranges [[1]] $ x.range`.然后我用它作为x位置:`x = xlim.range [1] - diff(xlim.range)/ 10`它的工作原理! (2认同)

bsc*_*idr 37

现在使用ggplot2 3.0.0很简单,因为现在可以通过调用禁用剪辑coord_cartesian(clip = 'off'),如下例所示.

    # Generate data
    df <- data.frame(y=c("cat1","cat2","cat3"),
                     x=c(12,10,14),
                     n=c(5,15,20))

    # Create the plot
    ggplot(df,aes(x=x,y=y,label=n)) +
      geom_point()+
      geom_text(x = 14.25, # Set the position of the text to always be at '14.25'
                hjust = 0,
                size = 8) +
      coord_cartesian(xlim = c(10, 14), # This focuses the x-axis on the range of interest
                      clip = 'off') +   # This keeps the labels from disappearing
      theme(plot.margin = unit(c(1,3,1,1), "lines")) # This widens the right margin
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 为了完整起见,`clip = off`也可以被称为@`coord_flip`(我也假设coord_*x*)。添加 `coord_cartesian(clip = 'off')` 对我来说不是一个解决方案,因为我需要 `coord_flip`。 (3认同)

Ste*_*hko 5

基于的更简单的解决方案 grid

require(grid)

df = data.frame(y = c("cat1", "cat2", "cat3"), x = c(12, 10, 14), n = c(5, 15, 20))

p <- ggplot(df, aes(x, y)) + geom_point() + # Base plot
theme(plot.margin = unit(c(1, 3, 1, 1), "lines"))

p

grid.text("20", x = unit(0.91, "npc"), y = unit(0.80, "npc"))
grid.text("15", x = unit(0.91, "npc"), y = unit(0.56, "npc"))
grid.text("5", x = unit(0.91, "npc"), y = unit(0.31, "npc"))
Run Code Online (Sandbox Code Playgroud)

  • 乍一看要简单得多,但是...字体与 ggplot2 默认值不匹配,因此您必须摆弄这些设置,并且由于使用 npc 单位而更难定位文本。可能最终也同样复杂。 (6认同)