R 防止ggplot2中的多层标题居中

R 防止ggplot2中的多层标题居中,r,ggplot2,plotmath,R,Ggplot2,Plotmath,这是我上一个问题()的第二部分 现在,问题涉及如何防止plotmath将文本居中以避免额外的间距(此处以黄色突出显示)。我希望一切都与情节的右侧对齐 (不幸的是,如果你的建议是这样的话,我不能用expression替换。) 有什么建议吗 库(ggplot2) ggplot(鸢尾属,aes(种,萼片长度))+ geom_箱线图()+ 实验室(标题=替换(顶部( 顶( displaystyle(“第1层很小”), displaystyle(“第二层稍微长一点”) ), “第三层是超级二层” )))

这是我上一个问题()的第二部分

现在,问题涉及如何防止
plotmath
将文本居中以避免额外的间距(此处以黄色突出显示)。我希望一切都与情节的右侧对齐

(不幸的是,如果你的建议是这样的话,我不能用
expression
替换
。)

有什么建议吗

库(ggplot2)
ggplot(鸢尾属,aes(种,萼片长度))+
geom_箱线图()+
实验室(标题=替换(顶部(
顶(
displaystyle(“第1层很小”),
displaystyle(“第二层稍微长一点”)
),
“第三层是超级二层”
)))

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

push <- function(from, to)
  sprintf(paste("%", max(nchar(from), max(nchar(to))), "s"), from)
现在坏消息是,
push
仅使用mono字体才能达到预期效果,这不是
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"))

最简单的方法可能是在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)

gtable_add_标题相关问题已经很少(请参见plotmath对齐)。例如,是否可以像中那样手动添加空格?与其手动尝试不同数量的空格,还不如将其自动化。是的,但问题是它们都使用
expression
创建标题,而我使用
substitute
。当然,提供的解决方案在使用
substitute
时效果不佳。(如果你想知道为什么我会痴迷于
替换
,这就是我使用它的上下文-)所以我想问题是文本的长度不是固定的。为什么不更新一下您的示例,手动添加(比如)30个空格并不能解决问题?那我就试试看。第二层和第三层的文本都是固定长度的,所以很容易修改。由于用户可以选择输入任意长度的
标题
,因此第1层
会有所不同。
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)