Making it easy to use various types of fonts ('TrueType', 'OpenType', Type 1, web fonts, etc.) in R graphs, and supporting most output formats of R graphics including PNG, PDF and SVG. Text glyphs will be converted into polygons or raster images, hence after the plot has been created, it no longer relies on the font files. No external software such as 'Ghostscript' is needed to use this package.
showtext makes it easy to use various types of fonts (TrueType, OpenType, Type 1, web fonts, etc.) in R graphs. It tries to do the following two things:
The motivation to develop this package is that using non-standard
fonts in R graphs (especially for PDF device) is not straightforward,
for example, to create PDF graphs with Chinese characters.
This is because most of the standard fonts used by
pdf() do not contain
Chinese character glyphs, and users could hardly use system fonts in R.
The extrafont package developed by
Winston Chang is one nice solution to this problem,
which mainly focuses on using TrueType fonts (
.ttf) in PDF graphics device.
Now showtext is able to support more font formats and more graphics devices,
and avoids using external software such as Ghostscript.
library(showtext)## Loading Google fonts ()font_add_google("Gochi Hand", "gochi")font_add_google("Schoolbell", "bell")font_add_google("Covered By Your Grace", "grace")font_add_google("Rock Salt", "rock")## Automatically use showtext to render text for future devicesshowtext_auto()## Tell showtext the resolution of the device,## only needed for bitmap graphics. Default is 96## showtext_opts(dpi = 96)set.seed(123)x = rnorm(10)y = 1 + x + rnorm(10, sd = 0.2)y = 5mod = lm(y ~ x)## Plotting functions as usual## Open a graphics device if you want, e.g.## png("demo.png", 700, 600, res = 96)## If you want to show the graph in a window device,## remember to manually open one in RStudio## See the "Known Issues" sectionx11()op = par(cex.lab = 2, cex.axis = 1.5, cex.main = 2)plot(x, y, pch = 16, col = "steelblue",xlab = "X variable", ylab = "Y variable", family = "gochi")grid()title("Draw Plots Before You Fit A Regression", family = "bell")text(-0.5, 4.5, "This is the outlier", cex = 2, col = "steelblue",family = "grace")abline(coef(mod))abline(1, 1, col = "red")par(family = "rock")text(1, 1, expression(paste("True model: ", y == x + 1)),cex = 1.5, col = "red", srt = 20)text(0, 2, expression(paste("OLS: ", hat(y) == 0.79 * x + 1.49)),cex = 1.5, srt = 15)legend("topright", legend = c("Truth", "OLS"), col = c("red", "black"), lty = 1)par(op)
In this example we first load some fonts that are available online
through Google Fonts, and then tell R
to render text using showtext by calling the
function. All the remaining part is exactly the same as the usual plotting
This example should work on most graphics devices, including
postscript(), and on-screen devices such as
x11() on Linux.
Let me first explain a little bit how
To my best knowledge, the default PDF device in R does not "draw" the text, but actually "describes" the text in the PDF file. That is to say, instead of drawing lines and curves of the actual glyph, it only embeds information about the text, for example what characters it has, which font it uses, etc.
However, the text with declared font may be displayed differently in
different OS, which means that the appearance of graph created by
system dependent. If you unfortunately do not have the declared font
in your system, you may not be able to see the text correctly at all.
In comparison, showtext package tries to solve this problem by converting text into color-filled polygonal outlines (for vector graphics) or raster images (for bitmap and on-screen graphics), thus having the same appearance under all platforms. People who view this graph do not need to install the font that creates the graph. It provides convenience to both graph makers and graph viewers.
More importantly, showtext can use system font files, so you can show text in the graph with your favourite font face, as long as it is supported by FreeType. See section Loading Fonts below.
To create a graph using a specified font, you simply do the following:
Only the steps marked with (*) are newly added. If you want to use
showtext globally, you can call the function
once, and then all the devices after that will automatically use
showtext to render text, as the example in the beginning shows.
If you want to have finer control on which part of the code should use
showtext_end() will help.
Only plotting functions enclosed by this pair of calls will use showtext,
and others not. For example, to change the title font only, we can do:
library(showtext)font_add_google("Schoolbell", "bell")## By default the automatic call of showtext is disabled## You can manually turn it off using the line below## showtext_auto(enable = FALSE)## To use showtext_begin() and showtext_end() you need to## explicitly open a graphics devicepng("demo.png", 700, 600, res = 96)set.seed(123)x = rnorm(10)y = 1 + x + rnorm(10, sd = 0.2)y = 5mod = lm(y ~ x)op = par(cex.lab = 1.5, cex.axis = 1.5, cex.main = 2)plot(x, y, pch = 16, col = "steelblue",xlab = "X variable", ylab = "Y variable")grid()## Use showtext only for this partshowtext_begin()title("Draw Plots Before You Fit A Regression", family = "bell")showtext_end()text(-0.5, 4.5, "This is the outlier", cex = 2, col = "steelblue")abline(coef(mod))abline(1, 1, col = "red")text(1, 1, expression(paste("True model: ", y == x + 1)),cex = 1.5, col = "red", srt = 20)text(0, 2, expression(paste("OLS: ", hat(y) == 0.79 * x + 1.49)),cex = 1.5, srt = 15)legend("topright", legend = c("Truth", "OLS"), col = c("red", "black"), lty = 1)par(op)dev.off()
Loading font is actually done by package sysfonts.
The easy way to load font into showtext is by calling
family is the name that you assign to that font (so that later you can
par(family = ...) to use this font in plotting), and
regular is the
path to the font file. That is to say, only knowing the "font name" is not
enough, since they are usually system dependent. On the contrary, font file
is the entity that actually provides the character glyphs.
Usually the font files are located in some "standard" directories in the system
(for example on Windows it is typically
You can use
font_paths() to check the current search path or add a new one,
font_files() to list available font files in the search path.
Below is an example to load system fonts on Windows:
library(showtext)## Add fonts that are available on Windowsfont_add("heiti", "simhei.ttf")font_add("constan", "constan.ttf", italic = "constani.ttf")library(ggplot2)p = ggplot(NULL, aes(x = 1, y = 1)) + ylim(0.8, 1.2) +theme(axis.title = element_blank(), axis.ticks = element_blank(),axis.text = element_blank()) +annotate("text", 1, 1.1, family = "heiti", size = 15,label = "\u4F60\u597D\uFF0C\u4E16\u754C") +annotate("text", 1, 0.9, label = 'Chinese for "Hello, world!"',family = "constan", fontface = "italic", size = 12)showtext_auto() ## automatically use showtext for new devices## on-screen devicex11()print(p)dev.off()## PDF devicepdf("showtext-example-3.pdf", 7, 4)print(p)dev.off()## PNG deviceggsave("showtext-example-4.png", width = 7, height = 4, dpi = 96)## turn off if no longer neededshowtext_auto(FALSE)
For other OS, you may not have the
simhei.ttf font file, but there is no
difficulty in using something else. At present
font_add() supports TrueType
fonts(*.ttf/*.ttc) and OpenType fonts(*.otf), and adding new
font type is trivial as long as FreeType supports it.
Also, there are many free fonts available and accessible on the web, for instance
the Google Fonts project (https://fonts.google.com/).
sysfonts provides an interface to automatically download and register those fonts
through the function
font_add_google(), as the example below shows.
library(showtext)font_add_google("Lobster", "lobster")showtext_auto()x11()plot(1, pch = 16, cex = 3)text(1, 1.1, "A fancy dot", family = "lobster", col = "steelblue", cex = 3)
showtext includes an open source CJK (Chinese, Japanese, and Korean) font
WenQuanYi Micro Hei.
If you just want to show CJK text in your graph, simply specify the
family name in plotting functions.
library(showtext)font_install(source_han_serif())font_families() "sans" "serif" "mono" "wqy-microhei" "source-han-serif-cn"
?source_han for more details.
Every graphics device in R implements some functions to draw specific graphical
polygon() to draw polygons,
raster() to display
textUTF8() to show text, etc. What
is to override their own text rendering functions and replace them by hooks
provided in showtext that will further call the device's
functions to draw the character glyphs.
This action is done only when you call
showtext_begin() and won't modify the
graphics device if you call
showtext_end() to restore the original device functions back.
showtext does not work well with the RStudio graphics device (RStudioGD).
Therefore, if you want to display graphs on a window device in RStudio,
you need to manually open one, e.g.,
x11() on Linux,
quartz() on Mac OS.