【问题标题】:preventing centering multilayered caption in ggplot2防止在ggplot2中居中多层标题
【发布时间】:2019-04-13 20:26:49
【问题描述】:

这是我上一个问题 (getting constant text size while using atop function in r) 的第二部分。

现在的问题与我如何防止 plotmath 使文本居中以避免多余的间距有关(此处以黄色突出显示)。我希望一切都与情节的右侧对齐。

(很遗憾,如果您的建议是这样的话,我无法将 substitute 替换为 expression。)

有什么建议吗?

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"
  )))

【问题讨论】:

  • 相关问题已经很少(参见 plotmath alignment)。例如,可以接受像stackoverflow.com/questions/35781950/… 中那样手动添加空格吗?与其实际手动尝试不同数量的空格,不如将其自动化。
  • 是的,但问题是他们都使用expression 来创建标题,而我使用的是substitute。当然,提供的解决方案不适用于substitute。 (如果您想知道为什么对substitute 如此着迷,这就是我使用它的那种背景-github.com/IndrajeetPatil/ggstatsplot/blob/…
  • 所以我想问题是文本不是固定长度的。您为什么不稍微更新一下您的示例,例如手动添加 30 个空格并不能解决问题?那我试试看。
  • layer 2layer 3 中的文本是固定长度的,这样很容易修复。 layer 1 会有所不同,因为用户可以选择输入任意长度的 caption

标签: r ggplot2 plotmath


【解决方案1】:

最简单的可能是在 gtable 中逐行添加文本 grobs,

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)

【讨论】:

    【解决方案2】:

    让我们从好消息开始。这是一个函数,它为from 添加足够的前导空格,使其与列表to 中最长的元素一样长:

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

    接下来我们有三层,也可以使用substitute(据我了解,在你的情况下只有第一个使用它)。

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

    现在坏消息是push 仅使用单色字体才能达到预期效果,这不是ggplot2 中的默认系列。关于字体的问题有很多,所以如果你愿意的话,也许你可以导入一些其他的单声道字体。

    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"))
    

    【讨论】:

      猜你喜欢
      • 2018-01-02
      • 1970-01-01
      • 2022-01-15
      • 2015-10-24
      • 2013-05-01
      • 1970-01-01
      • 2015-05-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多