Changing fonts in ggplot2
Solution 1
You just missed an initialization step I think.
You can see what fonts you have available with the command windowsFonts()
. For example mine looks like this when I started looking at this:
> windowsFonts()
$serif
[1] "TT Times New Roman"
$sans
[1] "TT Arial"
$mono
[1] "TT Courier New"
After intalling the package extraFont and running font_import
like this (it took like 5 minutes):
library(extrafont)
font_import()
loadfonts(device = "win")
I had many more available - arguable too many, certainly too many to list here.
Then I tried your code:
library(ggplot2)
library(extrafont)
loadfonts(device = "win")
a <- ggplot(mtcars, aes(x=wt, y=mpg)) + geom_point() +
ggtitle("Fuel Efficiency of 32 Cars") +
xlab("Weight (x1000 lb)") + ylab("Miles per Gallon") +
theme(text=element_text(size=16, family="Comic Sans MS"))
print(a)
yielding this:
Update:
You can find the name of a font you need for the family
parameter of element_text
with the following code snippet:
> names(wf[wf=="TT Times New Roman"])
[1] "serif"
And then:
library(ggplot2)
library(extrafont)
loadfonts(device = "win")
a <- ggplot(mtcars, aes(x=wt, y=mpg)) + geom_point() +
ggtitle("Fuel Efficiency of 32 Cars") +
xlab("Weight (x1000 lb)") + ylab("Miles per Gallon") +
theme(text=element_text(size=16, family="serif"))
print(a)
Solution 2
Another option is to use showtext
package which supports more types of fonts (TrueType, OpenType, Type 1, web fonts, etc.) and more graphics devices, and avoids using external software such as Ghostscript.
# install.packages('showtext', dependencies = TRUE)
library(showtext)
Import some Google Fonts
# https://fonts.google.com/featured/Superfamilies
font_add_google("Montserrat", "Montserrat")
font_add_google("Roboto", "Roboto")
Load font from the current search path into showtext
# Check the current search path for fonts
font_paths()
#> [1] "C:\\Windows\\Fonts"
# List available font files in the search path
font_files()
#> [1] "AcadEref.ttf"
#> [2] "AGENCYB.TTF"
#> [428] "pala.ttf"
#> [429] "palab.ttf"
#> [430] "palabi.ttf"
#> [431] "palai.ttf"
# syntax: font_add(family = "<family_name>", regular = "/path/to/font/file")
font_add("Palatino", "pala.ttf")
font_families()
#> [1] "sans" "serif" "mono" "wqy-microhei"
#> [5] "Montserrat" "Roboto" "Palatino"
## automatically use showtext for new devices
showtext_auto()
Plot: need to open Windows graphics device as showtext
does not work well with RStudio built-in graphics device
# https://github.com/yixuan/showtext/issues/7
# https://journal.r-project.org/archive/2015-1/qiu.pdf
# `x11()` on Linux, or `quartz()` on Mac OS
windows()
myFont1 <- "Montserrat"
myFont2 <- "Roboto"
myFont3 <- "Palatino"
library(ggplot2)
a <- ggplot(mtcars, aes(x = wt, y = mpg)) +
geom_point() +
ggtitle("Fuel Efficiency of 32 Cars") +
xlab("Weight (x1000 lb)") + ylab("Miles per Gallon") +
theme(text = element_text(size = 16, family = myFont1)) +
annotate("text", 4, 30, label = 'Palatino Linotype',
family = myFont3, size = 10) +
annotate("text", 1, 11, label = 'Roboto', hjust = 0,
family = myFont2, size = 10)
## On-screen device
print(a)
## Save to PNG
ggsave("plot_showtext.png", plot = a,
type = 'cairo',
width = 6, height = 6, dpi = 150)
## Save to PDF
ggsave("plot_showtext.pdf", plot = a,
device = cairo_pdf,
width = 6, height = 6, dpi = 150)
## turn showtext off if no longer needed
showtext_auto(FALSE)
Edit: another workaround to use showtext
in RStudio. Run the following code at the beginning of the R session (source)
trace(grDevices::png, exit = quote({
showtext::showtext_begin()
}), print = FALSE)
Solution 3
A simple answer if you don't want to install anything new
To change all the fonts in your plot plot + theme(text=element_text(family="mono"))
Where mono
is your chosen font.
List of default font options:
- mono
- sans
- serif
- Courier
- Helvetica
- Times
- AvantGarde
- Bookman
- Helvetica-Narrow
- NewCenturySchoolbook
- Palatino
- URWGothic
- URWBookman
- NimbusMon
- URWHelvetica
- NimbusSan
- NimbusSanCond
- CenturySch
- URWPalladio
- URWTimes
- NimbusRom
R doesn't have great font coverage and, as Mike Wise points out, R uses different names for common fonts.
This page goes through the default fonts in detail.
Solution 4
Late to the party, but this might be of interest for people looking to add custom fonts to their ggplots
inside a shiny
app on shinyapps.io.
You can:
This leads to the following upper section inside the app.R
file:
dir.create('~/.fonts')
file.copy("www/IndieFlower.ttf", "~/.fonts")
system('fc-cache -f ~/.fonts')
A full example app can be found here.
Solution 5
To change the font globally for ggplot2 plots.
theme_set(theme_gray(base_size = 20, base_family = 'Font Name' ))
EngBIRD
Updated on January 06, 2022Comments
-
EngBIRD over 2 years
Once upon a time, I changed my
ggplot2
font usingwindowsFonts(Times=windowsFont("TT Times New Roman"))
. Now, I can't get it off of this.In trying to set
family=""
inggplot2
theme()
, I can't seem to generate a change in fonts as I compile the MWE below with different font families.library(ggplot2) library(extrafont) loadfonts(device = "win") a <- ggplot(mtcars, aes(x=wt, y=mpg)) + geom_point() + ggtitle("Fuel Efficiency of 32 Cars") + xlab("Weight (x1000 lb)") + ylab("Miles per Gallon") + theme(text=element_text(size=16, # family="Comic Sans MS")) # family="CM Roman")) # family="TT Times New Roman")) # family="Sans")) family="Serif")) print(a) print("Graph should have refreshed")
R is returning a warning
font family not found in Windows font database
, but there was a tutorial I was following (if I can find it again I will update the link here) that said this was normal and not a problem. Also, somehow this worked at one point because my graph once used some arial or helvitica type font. I think this has always been a present warning even during the initial times migration.UPDATE
when I run
windowsFonts()
my output is$serif [1] "TT Times New Roman"
$sans [1] "TT Arial"
$mono [1] "TT Courier New"
But, this is after I ran
font_import()
so I can only conclude that my fonts are not being saved in the right place. The code that ran thefont_import()
request actually loads the libraries with:LocalLibraryLocation <- paste0("C:\\Users\\",Sys.getenv("USERNAME"),"\\Documents","\\R\\win-library\\3.2"); .libPaths(c(LocalLibraryLocation, .libPaths()))
-
EngBIRD over 8 yearsThanks for the help, half way there. I can toggle now between
mono||sans
(these look no different so far) andserif``, but not the actually name like
"TT Times New Roman", but additionally, I not sure that my
loadFonts` was successful. When I callfonts()
I have a list of nearly 300 fonts, but my guess is they weren't installed to the local environment making them accessible to the windows device. I am not sure if that makes any sense, but I tried to provide an update to my original question with snippets that might help. Thanks again! -
EngBIRD over 8 yearsThanks for that names snippet update, it looks very helpful, how did your comic sans Ms example produce the right appearance if the family is the only string my installation recognizes.
-
Mike Wise over 8 yearsLuck. In that font (and in a lot of others), the family name is the same as the family value. So
wf[which(wf=="Comic Sans MS")]
yields$``Comic Sans MS`` [1] "Comic Sans MS"
-
EngBIRD over 8 yearsThanks, do you know if it's possible to direct or load the fonts from a particular place? I.e. Even for the install of load fonts or specifying the fonts? I don't get the additional windows visible fonts when repeating the summary display call...
-
Mike Wise over 8 yearsDid you run font_import and loadfonts() right after each other?
-
EngBIRD over 5 yearsThanks, I look forward to trying this out!
-
Agile Bean over 5 yearsthank you a thousand times... the package makes it super easy to a) verify what font families you have available for ggplot by font_families() - b) look for the font file names by font_files() - c) adding the font file as a font family by font_add(family, font_file_name). Awesome!!!
-
Tung over 5 years@AgileBean: glad that I could help :)
-
ivo Welch over 5 yearsimportant: you must all install the XQuartz package from xquartz.org first, or you will get a non-descript error on trying to load the library.
-
GreenManXY over 3 yearsThis solutions does not work for me. I still get the default font, both in the window and the Rstudio's plot window.
-
maycca about 3 yearsFor some reason, this works for me if
family="mono"
andsans
. But, does not work forHelvetica
neitherHelvetica-Narrow
. here I got a classical warninggrid.Call.graphics(C_text, as.graphicsAnnot(x$label), ... : font family not found in Windows font database
. I have not added any further libraries likelibrary(extrafont) loadfonts(device = "win")
. Could this be a problem? Thanks! -
NCC1701 almost 3 yearsWhen I want to save as pdf it gives an error.
Roboto' not found in PostScript font database
-
dre over 2 yearsis there any chance this won't work on a work laptop due to not having admin access? i'm running the above process and it's not working for me... had a MacBook at my last job and this was never an issue, it just WORKS on a mac... thoughts?
-
Mike Wise over 2 yearsYou could definintely lock down a Windows laptop to prevent new fonts from being installed. And I imagine there are a lot of IT departments that would do exactly that and by design. And they could also probably lock down a MacBook too if they knew what they were doing.