2016-10-16 2 views
1

Im Folgenden zu Ansichtsfenster erzeugt ein 2 x 2 facettierten Grundstück, mit verschiedenen x und y im Bereich auf jeder der Facetten:ggplot2 Position geom_text oder geom_label relativ

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 

Jetzt habe ich auf einen Text/Etikett platzieren möchten jede der Facetten, etwa so:

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)) 

Wie kann ich die Positionierung des Text/label definieren, so dass es eine bestimmte Fraktion des Abstandes entlang der Facetten ist eben, etwa bei x = 0,75 ein y = 0,75 (drei Viertel horizontal und drei Viertel vertikal).

Mit anderen Worten, ich möchte, dass es relativ zum Ansichtsfenster der Facette positioniert wird, nicht die Werte der im Ansichtsfenster gerenderten Punkte.

+0

'annotation_custom()' würde helfen, wie Sie [ein TextGrob innerhalb eines grobTree positionieren konnte Füllen des Bedienfelds] (http://StackOverflow.com/a/32832732/471093). Allerdings [Hadley entschied, dass Anmerkungen immer für alle Panels gleich sein sollten] (https://github.com/hadley/ggplot2/issues/1399#issuecomment-155156602), und es ist nicht klar, wie man eine 'geom_'-Version von 'annotation_custom'. – baptiste

+0

Alternativ können Sie 'ggplot_build' verwenden, um alle relevanten Achsenlimits zu finden und die relativen Positionen in absolute umzurechnen. – baptiste

+0

@baptiste erstellt fraktionale Positionseinstellungsfunktion, siehe meine Antwort unten. –

Antwort

2

So landete ich eine 'Fraktion' Positionseinstellung zu schaffen auf, als solche:

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 
} 

)

, die im Falle meiner ursprünglichen Frage, sollte wie folgt aufgerufen werden:

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

fractional example