предотвращение центрирования многослойных титров в ggplot2 - PullRequest
0 голосов
/ 10 ноября 2018

Это часть 2 моего предыдущего вопроса ( получение постоянного размера текста при использовании функции atop в 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"
  )))

enter image description here

Ответы [ 2 ]

0 голосов
/ 11 ноября 2018

проще всего было бы добавлять строки текста за строкой в ​​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)
0 голосов
/ 10 ноября 2018

Начнем с хороших новостей. Вот функция, которая добавляет в 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. На SO есть несколько вопросов относительно шрифтов, так что, возможно, вы можете импортировать какой-нибудь другой моно шрифт, если хотите.

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

enter image description here

...