ggplot2相对于视口的位置geom_text或geom_label

时间:2016-10-16 23:26:40

标签: r ggplot2

以下产生2 x 2刻面图,每个刻面上有不同的x和y范围:

set.seed(1)
n = 4
x = runif(n)
y = runif(n)
df = data.frame(x,y)
cv = c(0,0.5,1)
df$facetx = letters[cut(df$x,cv)]
df$facety = letters[cut(df$y,cv)]

base = ggplot(data=df,aes(x,y)) + 
  geom_point() +
  facet_grid(facetx~facety,scales='free')
base

现在我想在每个方面放置一个文本/标签,如下所示:

df.labs       = expand.grid(facetx=c('a','b'),facety=c('a','b')); 
df.labs$label = sprintf("Label %s",1:nrow(df.labs))
base + 
  geom_text(data = df.labs,x=0.5,y=0.5,aes(label=label))

如何定义文本/标签的位置,以便精确地沿着小平面的某个部分距离,例如x = 0.75,y = 0.75(水平四分之三,垂直四分之三)

换句话说,我希望它相对于构面视口定位,而不是视口内渲染点的值。

1 个答案:

答案 0 :(得分:2)

所以我最终创造了一个'分数'位置调整,如:

position_fraction <- function(x=0.5,y=0.5) {
ggplot2:::ggproto(NULL, PositionFraction,
                  x = x,
                  y = y)
}

PositionFraction <- ggplot2:::ggproto("PositionFraction", ggplot2::Position,
x = 0.5,
y = 0.5,
required_aes = c("x", "y"),
setup_params = function(self, data) {
  list(x = self$x, 
       y = self$y)
},
compute_layer = function(self,data, params, panel) {
  layout = panel$layout
  data  = ddply(data,'PANEL',function(df){
    p   = df$PANEL[1]; ix = which(layout$PANEL == p)[1]
    sx  = panel$x_scales[[ layout$SCALE_X[ix]  ]]
    sy  = panel$y_scales[[ layout$SCALE_Y[ix] ]]
    f   = function(v,s){ lims = s$get_limits(); v*diff(lims) + min(lims) }
    df$x = params$x
    df$y = params$y
    ggplot2:::transform_position(df, function(x) f(x,sx), function(y) f(y,sy))
  })
  data
}

在原始问题的情况下,应该像这样调用:

base + 
  geom_text(data = df.labs,aes(label=label),position=position_fraction(.75,.75))

fractional example