将点和文本添加到ggplot annotation_grob中?

时间:2016-04-09 00:33:41

标签: r ggplot2

我想在my previous question中生成的图表中添加一些注释。

set.seed(40816)
library(ggplot2)
library(grid)
df.plot <- data.frame(x = rnorm(100, 0, 1))

strainerGrob <- function(pos=unit(4,"mm"), gp=gpar(lty=2, lwd=2))
segmentsGrob(0, unit(1,"npc") - pos, 1, unit(1,"npc") - pos, gp=gp)
ggplot(df.plot, aes(x = x)) + geom_density() +
  annotation_custom(strainerGrob(), xmin = -1, xmax = 1, ymin=-Inf, ymax=0)

enter image description here

我想在段的左侧添加-1,在右侧添加1,在0添加点,在点上方添加0。所有这一切,而不必使用y的绝对距离。这可能吗?现在我可以用y

进行编码
ggplot(df.plot, aes(x = x)) + geom_density() +
  annotation_custom(strainerGrob(), xmin = -1, xmax = 1, ymin=-Inf, ymax=0) +
  geom_point(aes(x=0, y=-0.01)) +
  annotate("text", x = -1, y = -0.01, label = -1, hjust = 1.5) +
  annotate("text", x = 1, y = -0.01, label = 1, hjust = -1) +
  annotate("text", x = 0, y = 0, label = 0, vjust = 2.75)

enter image description here

但是,如果我更改数据,那么点和其他注释最终会出错。

df.plot <- data.frame(x = rnorm(100, 0, 4))
ggplot(df.plot, aes(x = x)) + geom_density() +
  annotation_custom(strainerGrob(), xmin = -1, xmax = 1, ymin=-Inf, ymax=0) +
  geom_point(aes(x=0, y=-0.01)) +
  annotate("text", x = -1, y = -0.01, label = -1, hjust = 1.5) +
  annotate("text", x = 1, y = -0.01, label = 1, hjust = -1) +
  annotate("text", x = 0, y = 0, label = 0, vjust = 2.75)

enter image description here

1 个答案:

答案 0 :(得分:1)

grob可以是一个有多个孩子的gTree,例如

enter image description here

set.seed(40816)
library(ggplot2)
df.plot <- data.frame(x = rnorm(100, 0, 1))

strainerGrob <- function(range = c(-1,2), midpoint=0.35, 
                         vpos=unit(5,"mm"), 
                         pad = unit(1.5,"mm"), 
                         gp=gpar(lty=2, lwd=2)){

  labels <- as.character(c(range[1], midpoint, range[2]))
  xpos <- c(0, scales::rescale(midpoint, from=range, to=c(0,1)), 1)
  sg <- segmentsGrob(0, unit(1,"npc") - vpos, 1, unit(1,"npc") - vpos, gp=gp)
  tg <- textGrob(labels, x = unit(xpos, "npc") + c(-1,0,1)*pad,
                 hjust = c(1,0.5,0),
                 vjust=c(0.5,0,0.5), y=unit(1,"npc") - vpos + c(0,1,0)*pad)
  pg <- pointsGrob(x=xpos[2], y=unit(1,"npc") - vpos, pch = 19, gp = gpar(cex=0.5))

  grobTree(sg, pg, tg)
}


# wrapper to ensure that both geom and grob are in sync with x values
custom_range <- function(range = c(-1,2), midpoint=0.35, ...){
  sg <- strainerGrob(range=range, midpoint=midpoint, ...)
  annotation_custom(sg, xmin = range[1], xmax = range[2], ymin=-Inf, ymax=0)
}

ggplot(df.plot, aes(x = x)) + geom_density() +
  custom_range(c(-1, 2), 0.35) +
  expand_limits(y=-0.1)

如果您要在各种图表中使用某些内容,例如:有了facet,或者在多个位置,我建议你写一个自定义geom。对于一次性,annotation_custom可能没问题。