2012-09-13 3 views
43

Vorrei associare i valori di dimensione del campione con i punti su un grafico. Posso usare geom_text per posizionare i numeri vicino ai punti, ma questo è disordinato. Sarebbe molto più pulito allinearli lungo il bordo esterno della trama.ggplot2 - annotazione all'esterno del grafico

Per esempio, ho:

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) 

che produce questa trama: enter image description here

Io preferirei qualcosa di più simile a questo: enter image description here

so di poter creare un secondo lotto e utilizzare grid.arrange (a la this post) ma sarebbe noioso determinare la spaziatura dei tasti di testo per allineare con l'asse y. C'è un modo più semplice per farlo? Grazie!

+1

Questo potrebbe essere fatto con asse secondario che ho penso che sia in fase di sviluppo. Ma se vuoi provarlo, segui questo link https://groups.google.com/forum/?fromgroups=#!topic/ggplot2/_3Pm-JEoCqE –

+0

Hmm interessante ... Mi chiedevo se Hadley stava per implementalo. Tuttavia, sto ricevendo alcuni strani errori cercando di caricare 'devtools':' call: if (! Version_match) {error: argomento is of length zero'. – jslefche

+0

Tutto quello che posso dire è che devtools funziona per me. Dovresti provare a pubblicare una domanda se non riesci a risolverlo. –

risposta

42

Non è necessario disegnare un secondo grafico. È possibile utilizzare annotation_custom per posizionare i solchi ovunque all'interno o all'esterno dell'area di stampa. Il posizionamento dei grobs è in termini di coordinate dei dati. Supponendo che "5", "10", "15" siano allineati con "cat1", "cat2", "cat3", il posizionamento verticale dei textGrobs è curato - le coordinate y dei tuoi tre textGrobs sono date dal coordinate y dei tre punti dati. Per impostazione predefinita, le clip ggplot2 si espandono nell'area di disegno, ma il ritaglio può essere sovrascritto. Il margine pertinente deve essere ampliato per lasciare spazio al grob. Il seguente (usando ggplot2 0.9.2) dà una trama simile al vostro trama seconda:

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) 

enter image description here

+8

non è più facile avere uno strato di livello geom su x = Inf , hjust> = 1, e disattiva il clipping? – baptiste

+0

Funziona alla grande, grazie @ Sandy-Muspratt! – jslefche

+11

@jslefche, si dovrebbe notare che la soluzione offerta da @baptiste è molto più semplice. 'p = p + geom_text (aes (etichetta = n, x = Inf, y = y), hjust = -1)'. Quindi disattivare il ritaglio. Sebbene l'allineamento possa essere leggermente inferiore. –

2

soluzione più semplice basata su 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"))