ggplot2 - anota fuera de la trama

Resuelto jslefche asked hace 54 años • 6 respuestas

Me gustaría asociar valores de tamaño de muestra con puntos en un gráfico. Puedo usar geom_textpara colocar los números cerca de los puntos, pero esto es complicado. Sería mucho más limpio alinearlos a lo largo del borde exterior de la parcela.

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)

Lo que produce esta trama: ingrese la descripción de la imagen aquí

Preferiría algo más como esto: ingrese la descripción de la imagen aquí

Sé que puedo crear un segundo gráfico y usarlo grid.arrange(al estilo de esta publicación ), pero sería tedioso determinar el espaciado de los textGrobs para alinearlos con el eje y. ¿Hay alguna forma más fácil de hacer esto? ¡Gracias!

jslefche avatar Jan 01 '70 08:01 jslefche
Aceptado

Esto ahora es sencillo con ggplot2 3.0.0, ya que ahora el recorte se puede desactivar en los gráficos usando el clip = 'off'argumento en funciones de coordenadas como coord_cartesian(clip = 'off')o coord_fixed(clip = 'off'). A continuación se muestra un ejemplo.

    # Generate data
    df <- data.frame(y=c("cat1","cat2","cat3"),
                     x=c(12,10,14),
                     n=c(5,15,20))

    # Create the plot
    ggplot(df,aes(x=x,y=y,label=n)) +
      geom_point()+
      geom_text(x = 14.25, # Set the position of the text to always be at '14.25'
                hjust = 0,
                size = 8) +
      coord_cartesian(xlim = c(10, 14), # This focuses the x-axis on the range of interest
                      clip = 'off') +   # This keeps the labels from disappearing
      theme(plot.margin = unit(c(1,3,1,1), "lines")) # This widens the right margin

ingrese la descripción de la imagen aquí

bschneidr avatar Jul 12 '2018 18:07 bschneidr

No es necesario que estés dibujando una segunda trama. Puede utilizar annotation_custompara colocar grobs en cualquier lugar dentro o fuera del área de trazado. El posicionamiento de los grobs se realiza en términos de coordenadas de datos. Suponiendo que "5", "10", "15" se alinean con "cat1", "cat2", "cat3", se cuida el posicionamiento vertical de los textGrobs: las coordenadas y de sus tres textGrobs vienen dadas por Coordenadas y de los tres puntos de datos. De forma predeterminada, ggplot2los clips se desplazan al área de trazado, pero el recorte se puede anular. Es necesario ampliar el margen pertinente para dejar espacio al grob. Lo siguiente (usando ggplot2 0.9.2) proporciona un gráfico similar al segundo gráfico:

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)

ingrese la descripción de la imagen aquí

Sandy Muspratt avatar Sep 14 '2012 02:09 Sandy Muspratt

Solución más sencilla basada engrid

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"))
Stepan S. Sushko avatar Sep 05 '2017 12:09 Stepan S. Sushko