preventing centering multilayered caption in ggplot2

大兔子大兔子 提交于 2019-12-12 11:31:07

问题


This is part-2 to my previous question (getting constant text size while using atop function in r).

Now the issue relates to how I can prevent plotmath from centering the text to avoid the extra spacing (highlighted here in yellow). I want everything aligned to the right side of the plot.

(Unfortunately, I can't replace substitute with expression if that's what your suggestion is going to be.)

Any suggestions?

library(ggplot2)

ggplot(iris, aes(Species, Sepal.Length)) +
  geom_boxplot()  +
  labs(caption = substitute(atop(
    atop(
      displaystyle("layer1 is small"),
      displaystyle("layer2 is a bit longer")
    ),
    "layer3 is super-duper longgggggggg"
  )))


回答1:


Let's start with good news. Here's a function that adds enough leading spaces to from as to be as long as the longest element from the list to:

push <- function(from, to)
  sprintf(paste("%", max(nchar(from), max(nchar(to))), "s"), from)

Next we have three layers, which also may use substitute (as I understand, in your case only the first one uses it).

l1 <- substitute("layer1 is small")
l2 <- "layer2 is a bit longer"
l3 <- "layer3 is super-duper longgggggggg"

Now the bad news is that push achieves the desired effect only with mono fonts, which is not the default family in ggplot2. There are multiple question on SO regarding fonts, so perhaps you may import some other mono font, if you prefer.

ggplot(iris, aes(Species, Sepal.Length)) +
  geom_boxplot()  +
  labs(caption = substitute(atop(atop(textstyle(l1), textstyle(l2)), textstyle(l3)), 
                            list(l1 = push(l1, list(l2 ,l3)),
                                 l2 = push(l2, list(l1, l3)), 
                                 l3 = push(l3, list(l2, l3))))) +
  theme(plot.caption = element_text(family = "mono"))




回答2:


easiest might be to add text grobs row by row in a gtable,

gtable_add_caption <- function(p, cap, g = ggplotGrob(p), 
                               hjust=1, x=unit(1,"npc"), pad = unit(c(2,2),"mm"),
                               ...){

  for(ii in seq_along(cap)){
    line <- tryCatch(parse(text = cap[ii]), error = function(e) cap[ii])
    tg <- textGrob(line, x = x - pad[1], hjust = hjust, gp=gpar(...))
    hg <- grobHeight(tg) 
    g <- gtable_add_rows(g, hg + pad[2])
    g <- gtable_add_grob(g, tg, t = nrow(g), l=1, r=ncol(g))
  }

  g
}

p <- ggplot()
ggplot(iris, aes(Species, Sepal.Length)) +
  geom_boxplot() ->p
g <- gtable_add_caption(p, c("first line", "integral(frac(1,x-1)*dx,alpha,beta)", "thirdddddddddddddddddd line"))
grid.newpage()
grid.draw(g)


来源:https://stackoverflow.com/questions/53239765/preventing-centering-multilayered-caption-in-ggplot2

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!