2

I want to style ggplot2 axis labels, by making some text bold. Ideally I would like to control the font size too. Is it all possible? Here is the example of what I am trying to do:

qplot(x = x,  y = y, data = data.frame(x = rnorm(10), y = rnorm(10))) + 
labs(x = "14pt Bold text \n12pt normal text")

So instead of 14pt Bold text I want 14pt bold font, and for 12pt normal text I want 12pt normal text.

I've googled for examples and all I found is the way to change the appearance of all the label, or using plotmath expressions, which strangely had no effects on ggplot2, i.e doing labs(x=expression("bold(Bold text)")) had no effect.

Update

As always I tried to ask a too general question. The full example I want to achieve also involves using custom fonts. The fonts I am using are AvenirNextLTPro, and the look I am going for is the following:

library(showtext)
library(ggplot2)

font.add("AvenirNextLTPro", 
         regular = "AvenirNextLTPro-Regular.otf", 
         bold="AvenirNextLTPro-Demi.otf",    
         italic = "AvenirNextLTPro-It.otf", 
         bolditalic = "AvenirNextLTPro-DemiIt.otf")
showtext.auto() 

ggplot(data = data.frame(x = rnorm(10), y = rnorm(10)), aes(x = x, y = y)) + 
    geom_point() + 
    labs(x = "14pt Bold text \n12pt normal text", 
         y = "14 pt Bold text\n\n 12pt\nnormal\ntext") + 
    theme(axis.title.y = element_text(angle = 0, hjust = 1, family = "AvenirNextLTPro"), axis.title.x = element_text(family = "AvenirNextLTPro"))

Note that for this to work you need to install the fonts, i.e. they should be visible for font.files(). For Mac OS X this can be achieved by opening the Font app and adding the downloaded fonts.

mpiktas
  • 11,258
  • 7
  • 44
  • 57
  • 1
    Check if any of these answers help [Different font faces and sizes within label text entries in ggplot2](http://stackoverflow.com/questions/6653193/different-font-faces-and-sizes-within-label-text-entries-in-ggplot2) – Pierre L Oct 03 '16 at 13:22
  • For the `plotmath` your example code would work using `expression(bold("Bold text"))`. You could add in an `atop` to this, but the spacing from `atop` is often not what we want. See `labs(x=expression(atop(bold("Bold text"), "Normal text")))`. – aosmith Oct 03 '16 at 15:26
  • I am also using this with the package showtext and for that plotmath expression bold does not work. – mpiktas Oct 04 '16 at 06:23
  • @aosmith, I've updated the question with the code for which bold expression does not work. I suspect this might be platform related. Note however that specifying bold font in `element_text` picks the bold font. – mpiktas Oct 04 '16 at 06:37

2 Answers2

4

The answer-in-comment by Pierre is a very good way to handle this in a more generic fashion. However, with the new caption plot/theme element (install the github version of ggplot2 until it's released later this month) you can do a quick hack if all you want is what you've described.

ggplot(data.frame(x=rnorm(10), y=rnorm(10))) +
  geom_point(aes(x, y)) +
  labs(x="14pt Bold text", caption="12pt normal text") +
  theme(axis.title.x=element_text(size=14, face="bold", hjust=0.5)) +
  theme(plot.caption=element_text(size=12, face="plain", hjust=0.5))

enter image description here

Also, please try to avoid the tempting shortcut of qplot(). I spent some time removing that from the vast majority of the examples and it's use is not encouraged by the package author himself.

UPDATE

This is a gosh awful hack, but…

ggplot(data.frame(x=rnorm(10), y=rnorm(10))) +
  geom_point(aes(x, y)) +
  labs(x="14pt Bold text", caption="12pt normal text") +
  theme(axis.title.x=element_text(size=14, face="bold", hjust=0.5)) +
  theme(plot.caption=element_text(size=12, face="plain", hjust=0.5)) -> gg

grid.arrange(gg, left=textGrob("Title", rot=90, hjust=-0.3,
                               gp=gpar(fontsize=14, fontface="bold")))

enter image description here

will get you the same thing on the y axis. You can modify the spacing a bit if needed but you will no doubt need to tweak the hjust for any "production"/publication plots.

hrbrmstr
  • 77,368
  • 11
  • 139
  • 205
  • Yes I saw the caption, but unfortunately I need to style the y axis label too. I suppose it will not work then? – mpiktas Oct 03 '16 at 13:33
  • 1
    Ugh, aye. The grob editing that Pierre noted is most likely your only real option… but (lemme try something) – hrbrmstr Oct 03 '16 at 13:45
0

The final solution (approximate to certain tweaking) I came up, based on @hrbmstr suggestion is the following.

library(showtext)
library(ggplot2)
library(gridExtra)

font.add("AvenirNextLTPro", 
         regular = "AvenirNextLTPro-Regular.otf", 
         bold="AvenirNextLTPro-Demi.otf",    
         italic = "AvenirNextLTPro-It.otf", 
         bolditalic = "AvenirNextLTPro-DemiIt.otf")
showtext.auto() 

gg<-ggplot(data = data.frame(x = rnorm(10), y = rnorm(10)), aes(x = x, y = y)) + 
    geom_point()+
    theme(axis.title.y = element_blank(), axis.title.x = element_blank())

grid.newpage()
gt <- ggplot_gtable(ggplot_build(gg))

t1 <- textGrob("Left upper text",y=unit(0,"npc"),just="bottom",gp = gpar(fontsize=14,fontfamily="AvenirNextLTPro",fontface="bold.italic"))
t2 <- textGrob("Left lower text",y=unit(1,"npc"),just="top", gp = gpar(fontsize=12,fontfamily="AvenirNextLTPro",fontface="italic"))
b1 <- textGrob("Bottom upper text",y=unit(0,"npc"),just="bottom", gp = gpar(fontsize=14,fontfamily="AvenirNextLTPro",fontface="bold.italic"))
b2 <- textGrob("Bottom lower text",y=unit(1,"npc"),just="top", gp = gpar(fontsize=12,fontfamily="AvenirNextLTPro",fontface="italic"))

lay2 <- rbind(c(1,3),c(2,3),c(NA,4),c(NA,5))

grid.arrange(t1,t2,gt,b1,b2, layout_matrix = lay2, widths=unit(c(0.15,0.85),"npc"), heights=unit(c(0.9/2,0.9/2,0.1/2,0.1/2),"npc"))

enter image description here It is for certain not a prettiest hack, but the one which allows quite a lot flexibility and the most importantly is sufficient in this particular case.

mpiktas
  • 11,258
  • 7
  • 44
  • 57