Want to change the font used in your R plots? I got a quite simple solution that works on Mac OS.
You need the function 'quartzFonts'. With this function, you can define additional font families to use in your R base graphic plots. The default font families are 'sans', 'serif' and 'mono'.
Let's say, I want to define a new font family with the 'Avenir' font. All I have to do is:
quartzFonts(avenir = c("Avenir Book", "Avenir Black", "Avenir Book Oblique",
"Avenir Black Oblique"))
The first element of the vector is the normal face, then bold face, then italic face, then bold-italic font face. The bold face is used for the title of the plots, for example.
Now, R knows how to interpret the font family 'avenir'. Let's try this:
par(family = 'sans') # the default of R
plot(rnorm(100), rnorm(100), main = "A plot.")
# Now, do the same with the new 'Avenir' font family
par(family = 'avenir') # the call to 'quartzFonts' above has to be executed first
plot(rnorm(100), rnorm(100), main = "Another plot.")
You might wonder where you can get the font names from. Well, simply open your Mac OS "Font Book" (it's called "Schriftsammlung" in German) and look at the title of the font that is written in grey over the sample of the font.
I defined a function '.define.fonts' in my .Rprofile file. So, each time R starts up, I have an invisible function '.define.fonts' available in the environment. If I want to use one of the two alternative fonts, I can just call '.define.fonts()'. Here's the function:
.define.fonts <- function () {
quartzFonts(avenir = c("Avenir Book", "Avenir Black", "Avenir Book Oblique",
"Avenir Black Oblique"), helvetica = c("Helvetica Neue Light",
"Helvetica Neue Bold", "Helvetica Neue Light Italic",
"Helvetica Neue Bold Italic"))
}
You might need to change the names of the 'helvetica' family if you run a non-German Mac OS.
5
This was a great blog post, thanks! I really like Helvetica Light. When I try to save my graph to a pdf, though, the text doesn't show up or I get an error (depending on how I try to save it). Do you happen to know a fix for that?
ReplyDeleteHey Anne, thanks for your reply. You are right: It does not work with PDFs and the font association with pdfFonts() works differently. However, I found a nice package that might solve your problem: It is called "extrafont" (https://cran.r-project.org/web/packages/extrafont/README.html).
DeleteI successfully adapted the fonts used in PDF output with the following commands:
install.packages('extrafont')
library(extrafont)
font_import() # This takes some time! But you only have to do it once.
loadfonts()
fonts()
pdf("test.pdf", family = "Impact")
plot(rnorm(100), xlab = "FONT test test öäü")
dev.off()
pdf("test2.pdf", family = "Luminari")
plot(rnorm(100), xlab = "FONT test test öäü")
dev.off()
pdf("test3.pdf", family = "Cambria")
plot(rnorm(100), xlab = "FONT test test öäü")
dev.off()
Helvetica wasn't imported by the package, though :(
Hi Sascha,
DeleteThanks a lot for sharing this. I did eventually get it to work with Helvetica Light, though it wasn't very straightforward. I had to manually change the name of the font family in a .csv file somewhere (sorry I can't remember where). I think this is only an issue for fonts that are nested under another name (like Helvetica Light underneath Helvetica).
font family 'avenir' not found in PostScript font database
ReplyDeleteHow do I deal with that? I am trying the save plots as .pdf files.
This is my code:
pdf("tmp/plot1.pdf",width = 6.5,height = 7.5)
quartzFonts(avenir = c("Avenir Book", "Avenir Black", "Avenir Book Oblique",
"Avenir Black Oblique"), helvetica = c("Helvetica Neue Light",
"Helvetica Neue Bold", "Helvetica Neue Light Italic",
"Helvetica Neue Bold Italic"))
plot_data<-c(0.4,0.4,0.2)
names(plot_data)<-c("A","B","C")
par(family = 'avenir') # the call to 'quartzFonts' above has to be executed first
pie(plot_data,las=2,main=NA,cex=0.7, init.angle =0,lty = 1,xlab="")
title("NORMAL",line=-1)
title(xlab="abc", line=-1)
dev.off()
Hi Gurkan, thanks for your comment. To be honest, I don't know how much of the R-internal plotting engine changed since I posted this. But this seems to work:
DeletequartzFonts(avenir = c("Avenir Book", "Avenir Black", "Avenir Book Oblique",
"Avenir Black Oblique"), helvetica = c("Helvetica Neue Light",
"Helvetica Neue Bold", "Helvetica Neue Light Italic",
"Helvetica Neue Bold Italic"))
plot_data<-c(0.4,0.4,0.2)
names(plot_data)<-c("A","B","C")
pie(plot_data,las=2,main=NA,cex=0.7, init.angle =0,lty = 1,xlab="", family = "avenir")
title("NORMAL",line=-1, family = "avenir")
title(xlab="abc", line=-1, family = "avenir")
As you can see, I deleted the par(family = "avenir") call and put the 'family' argument in each call. This works on my system.