Search code examples
rggplot2plotmath

Equal spacing with multiple atop


I'm trying to create a legend in a ggplot2 graph with multiple lines and a parameter and value on each line. Since I have symbols as variables, this needs to be done with expression. To create new lines, I have used multiple atop commands, but this leads to uneven spacing in the final line. Please see my following example:

library(ggplot2)

N = 25

a = -5
b = 2
sigma = 1

x = runif(N, 0, 10)
y = a + x * b + rnorm(N, sd = sigma)

df = data.frame(x, y)

ggplot(df, aes(x, y)) +
  geom_point() +
  geom_label(aes(x = 1, y = max(y) - 2),
             label = paste0("atop(atop(",
                            "textstyle(a == ", a, "),",
                            "textstyle(b == ", b, ")),",
                            "textstyle(sigma == ", sigma, "))"
             ), parse = TRUE
  )
ggsave("plotmath_atop.png", width = 6, height = 4, scale = 1)

This gives the following plot:plotmath with atop As you can see, the spacing between the lines b=2 and \sigma=1 is noticeably larger than the spacing between the lines a=-5 and b=2.

Is there a way of using expression with multiple line breaks while still having even spacing between each line?


Solution

  • you could use gridExtra::tableGrob,

    enter image description here

    library(gridExtra)
    library(grid)
    
    table_label <- function(label, params=list())  {
    
      params <- modifyList(list(hjust=0, x=0), params)
    
      mytheme <- ttheme_minimal(padding=unit(c(1, 1), "mm"), 
                                core = list(fg_params = params), parse=TRUE)
      disect <- strsplit(label, "\\n")[[1]]
      m <- as.matrix(disect)
      tg <- tableGrob(m, theme=mytheme)
      bg <- roundrectGrob(width = sum(tg$widths) + unit(3, "mm"), height = sum(tg$heights) + unit(3, "mm"))
      grobTree(bg, tg)
    
    }
    
    txt <- 'a == -5\n
            b == 2\n
            sigma == 1'
    
    
    library(ggplot2)
    
    qplot(1:10,1:10) +
      annotation_custom(table_label(txt), xmin=0, xmax=5, ymin=7.5)