Как выровнять заголовок ggplot с окном, а не сеткой сетки?

В версии ggplot2 версии 0.9 изменилось поведение выравнивания названия сюжета. В то время как в v0.8.9 выравнивание относилось к окну графика, в v0.9 выравнивание относилось к сетке построения графика.

Теперь, в то время как я в основном согласен с тем, что это желательно поведение, у меня довольно часто есть очень длинные сюжетные сюжеты.

Вопрос: Есть ли способ выравнивания названия сюжета с окном графика, а не сеткой графика?

Я ищу решение, которое автоматически выравнивает график. Другими словами, ручное выравнивание с использованием hjust не сработало бы для меня (я запускаю это на сотнях графиков для каждого проекта).

Также приемлемо любое решение, которое использовало grid.


Пример кода и графика: (Обратите внимание, как заголовок усекается справа от окна).

dat <- data.frame(
  text = c(
    "It made me feel very positive to brand X", 
    "It was clear and easy to understand",
    "I didn't like it al all"),
  value=runif(3)
)
library(ggplot2)
ggplot(dat, aes(text, value)) + 
  geom_bar(stat="identity") +
  coord_flip() +
  opts(title="Thinking about the ad that you've just seen, do you agree with the following statements? I agree that...") +
  theme_bw(16)

enter image description here

Ответ 1

В ggplot2 0.9 вы можете легко изменить макет.

p <- ggplot(dat, aes(text, value)) + 
  geom_bar(stat="identity") +
  coord_flip() +
  opts(title="Thinking about the ad that you've just seen,\ndo you agree with the following statements?\nI agree that...") +
  theme_bw(16)

gt <- ggplot_gtable(ggplot_build(p))
gt$layout[which(gt$layout$name == "title"), c("l", "r")] <- c(1, max(gt$layout$r))
grid::grid.draw(gt)

Возможно, в будущей версии ggplot2 предоставит согласованные интерфейсы для настройки макета.

enter image description here

Ответ 2

Здесь решение под ggplot2 2.2.1. Функция устраивает текстовый объект заголовка в верхнем центре ggplot.

library(ggplot2)
library(grid)
library(gridExtra)

# A function that puts a title text object centered above a ggplot object "p"
add_centered_title <- function(p, text, font_size){

  title.grob <- textGrob(
    label = text,
    gp = gpar(fontsize = font_size)
  )
  p1 <- arrangeGrob(p, top = title.grob)
  grid.draw(p1)
}

# Create the chart from your sample data
 test_chart <- ggplot(dat, aes(text, value)) + 
  geom_bar(stat="identity") +
  coord_flip() +
  theme_bw(16)

# Usage:
add_centered_title(test_chart,
                   "Thinking about the ad that you've just seen, do you agree with the following statements? I agree that...",
                   10)

# Or you can pipe a ggplot into this function using the %>% dplyr pipe:
library(dplyr)
test_chart %>%
  add_centered_title("Thinking about the ad that you've just seen, do you agree with the following statements? I agree that...",
                     10)