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