ggplot2 - annotate outside of plot

前端 未结 3 1709
青春惊慌失措
青春惊慌失措 2020-11-22 06:32

I would like to associate sample size values with points on a plot. I can use geom_text to position the numbers near the points, but this is messy. It would b

相关标签:
3条回答
  • 2020-11-22 07:05

    Simplier solution based on 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"))
    
    0 讨论(0)
  • 2020-11-22 07:09

    This is now straightforward with ggplot2 3.0.0, since now clipping can be disabled in plots by using the clip = 'off' argument in coordinate functions such as coord_cartesian(clip = 'off') or coord_fixed(clip = 'off'). Here's an example below.

        # 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
    

    0 讨论(0)
  • 2020-11-22 07:13

    You don't need to be drawing a second plot. You can use annotation_custom to position grobs anywhere inside or outside the plotting area. The positioning of the grobs is in terms of the data coordinates. Assuming that "5", "10", "15" align with "cat1", "cat2", "cat3", the vertical positioning of the textGrobs is taken care of - the y-coordinates of your three textGrobs are given by the y-coordinates of the three data points. By default, ggplot2 clips grobs to the plotting area but the clipping can be overridden. The relevant margin needs to be widened to make room for the grob. The following (using ggplot2 0.9.2) gives a plot similar to your second plot:

    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

    0 讨论(0)
提交回复
热议问题