Justace Clutter
Justace Clutter

Reputation: 2186

ggplot Multiline Title with Different Font Sizes

<SlightlyLookingAway>I am attempting to reproduce an excel plot in R.</SlightlyLookingAway> The Excel plot has a two line title. I know how to handle this by putting a '\n' in the title text. What I do not know how to handle is that the first line has a larger font size than the second row of the title... I have done some google searching and have come up with a general lack of response.

I realize that I might be able to cobble something together with an annotation of some kind but that seemed like a kludge. If that is the only answer then it is, but I wanted to ask the community first.

Any ideas?

Upvotes: 1

Views: 1147

Answers (3)

O. Bertrand
O. Bertrand

Reputation: 81

To perfectly center everything (which \n will not do), adapt every size of text whatever the number of lines and at the same time being able to adjust the interlinear space, use this instead:

e.g. for smaller to larger text size

ggtitle(expression(atop(scriptscriptstyle("whateverline1"),atop(scriptstyle("whateverline2"),atop(scriptscriptstyle(""),textstyle("whateverline3"))))))

Then use labeller=label_parsed

This also works for facet_grid, xlab and ylab

Note the scriptscriptstyle("") to control spacing between lines. You can also use varied relative sizes of text using scriptstyle or scriptscriptstyle or textstyle depending on your needs and of course use element_text(size=whatevernumber) in the theme section

Upvotes: 1

baptiste
baptiste

Reputation: 77124

try this,

library(gridExtra)

titleGrob <- function(x=c("First line", "second line"), size=10, ...){
  n <- length(x)
  size <- rep(size, length.out=n)
  one_label <- function(x, size, ...)
    textGrob(x, gp=gpar(fontsize=size), ...)
  lg <- mapply(one_label, x=x, size=size, ..., SIMPLIFY=FALSE)

  wg <- lapply(lg, grobWidth) 
  hg <- lapply(lg, grobHeight) 

  widths <- do.call(unit.c, wg)
  heights <- do.call(unit.c, hg) 

  maxwidth <- max(widths)
  g <- frameGrob(layout = grid.layout(n, 1, width=maxwidth, height=heights) )
  for(ii in seq_along(lg))
    g <- placeGrob(g, lg[[ii]], row=ii)

  g
}

grid.newpage()
g <- titleGrob(size=c(18,12))
grid.arrange(qplot(1,1), top=g)

Upvotes: 1

Justace Clutter
Justace Clutter

Reputation: 2186

It looks as though I have found a hacked solution which gets the job done but does not offer a lot of flexability. The idea is to put in a math expression using the atop() command along with the bold() and scriptstyle() functions.

myplot + 
ggtitle(expression(atop(bold("This is the Top Line"), scriptstyle("This is the second line")))) + 
theme(plot.title = element_text(size = 20))

If you know of a better solution with more control over the line spacing and even being able to adjust the font face, please let me know...

Upvotes: 1

Related Questions