2012-09-13 17 views
43

Me gustaría asociar valores de tamaño de muestra con puntos en una parcela. Puedo usar geom_text para posicionar los números cerca de los puntos, pero esto es desordenado. Sería mucho más limpio alinearlos a lo largo del borde exterior de la trama.ggplot2 - anotar fuera de la gráfica

Por ejemplo, tengo:

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) 

que produce esta trama: enter image description here

yo preferiría algo más parecido a esto: enter image description here

sé que puedo crear una segunda parcela y use grid.arrange (a la this post), pero sería tedioso determinar el espaciado de textGrobs para alinearse con el eje y. ¿Hay alguna forma más fácil de hacer esto? ¡Gracias!

+1

Esto podría hacerse con el eje secundario que I creo que está en desarrollo. Pero si quieres probarlo, sigue este enlace https://groups.google.com/forum/?fromgroups=#!topic/ggplot2/_3Pm-JEoCqE –

+0

Hmm interesante ... Me preguntaba si Hadley iba a implementar esto Sin embargo, estoy recibiendo algunos errores extraños al intentar cargar 'devtools':' call: if (! Version_match) {error: el argumento es de longitud cero'. – jslefche

+0

Todo lo que puedo decir es que devtools funciona para mí. Deberías intentar publicar una pregunta si no puedes resolverla. –

Respuesta

42

No necesita dibujar un segundo gráfico. Puede usar annotation_custom para posicionar grobs en cualquier lugar dentro o fuera del área de trazado. El posicionamiento de los grobs está en términos de coordenadas de datos. Asumiendo que "5", "10", "15" se alinean con "cat1", "cat2", "cat3", se ocupa el posicionamiento vertical de textGrobs - las coordenadas y de sus tres textGrobs están dadas por y-coordenadas de los tres puntos de datos. De forma predeterminada, ggplot2 clips grobs en el área de trazado, pero el recorte se puede anular. El margen relevante debe ampliarse para dejar espacio para el grob. La siguiente (utilizando ggplot2 0.9.2) da una trama similar a su segunda trama:

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

no es más fácil tener una capa de geom_text en x = Inf , hjust> = 1, ¿y desactivar el recorte? – baptiste

+0

Funciona muy bien, gracias @ Sandy-Muspratt! – jslefche

+11

@jslefche, debe tener en cuenta que la solución ofrecida por @baptiste es mucho más simple. 'p = p + geom_text (aes (label = n, x = Inf, y = y), hjust = -1)'. Luego apaga el recorte. Aunque la alineación puede estar un poco apagada. –

2

solución más simple basado en 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")) 
Cuestiones relacionadas