68

I am looking for a way to modify font types in ggplot. At the moment I would be happy enough to simply change fonts to the 'courier' font family, but ultimately my goal is to call a custom font template--any input on this latter point would be very much appreciated.

I've done a bit of homework, looking at the following posts and articles:

It may be because I am still a hopeless amateur with ggplot2, but I haven't even been able to switch chart fonts to courier. Any help? I've included the data for the chart in question, below, along with the code, so hopefully this is all easy enough to follow.

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
aaron
  • 6,339
  • 12
  • 54
  • 80

7 Answers7

34

I think your answer is fine but you can do it more simply:

install.packages("extrafont");library(extrafont)
font_import("Trebuchet MS")
library(ggplot2)
qplot(1:10)+theme(text=element_text(family="Trebuchet MS"))
Steve Powell
  • 1,646
  • 16
  • 26
  • As far as I can tell, for ``annotate()`` you need to supply the font information, e.g. ``family = myfamily, fontface = myfontface`` where the ``myfamily`` and ``myfontface`` should be consistent with what is passed to ``theme()`` as per your approach. A bit of a nuisance if you have a several ``annotate()`` calls. I haven't checked but I don't think the answer above deals with ``annotate()`` either. – PatrickT Dec 04 '14 at 09:15
31

Sorted out my query with fairly minimal hassle. It was a two-step solution that I wouldn't have arrived at without following the advice of the members who responded.

To change the ggplot text defaults, I adapted the code that Brandon referred me to at:

http://johndunavent.com/combined-line-and-bar-chart-ggplot2

Where John Dunavent creates a function, theme_min, that can be edited to provide the default options for a ggplot, including using fonts imported from Windows with the windowsFonts command. My adaptation of his code looks like this:

theme_min = function (size=10, font=NA, face='plain', 
    panelColor=backgroundColor, axisColor='#999999', 
    gridColor=gridLinesColor, textColor='black') 
{
    theme_text = function(...)
        ggplot2::theme_text(family=font, face=face, colour=textColor, 
            size=size, ...)

opts(
    axis.text.x = theme_text(),
    axis.text.y = theme_text(),
    axis.line = theme_blank(),
    axis.ticks = theme_segment(colour=axisColor, size=0.25),
    panel.border = theme_rect(colour=backgroundColor),
    legend.background = theme_blank(),
    legend.key = theme_blank(),
    legend.key.size = unit(1.5, 'lines'),
    legend.text = theme_text(hjust=0),
    legend.title = theme_text(hjust=0),
    panel.background = theme_rect(fill=panelColor, colour=NA),
    panel.grid.major = theme_line(colour=gridColor, size=0.33),
    panel.grid.minor = theme_blank(),
    strip.background = theme_rect(fill=NA, colour=NA),
    strip.text.x = theme_text(hjust=0),
    strip.text.y = theme_text(angle=-90),
    plot.title = theme_text(hjust=0),
    plot.margin = unit(c(0.1, 0.1, 0.1, 0.1), 'lines'))
}

##Create a custom font type. Could be 'F', 'TEST', whatever
windowsFonts(F = windowsFont('Wide Latin'))

##and insert this line of code into the original code I list above: 
+ theme_min(font='F', size=10) 

Awkwardly, there is no way (that I found) to generically modify the font settings for geom_text objects before a plot is created. James' solution above worked perfectly for this, though. Instead of using a standard font, I set fontfamily="F" to bring in the custom font that I selected in theme_min(), i.e.:

grid.gedit("GRID.text",gp=gpar(fontfamily="F"))

Hopefully this is useful to any other users looking to modify fonts on their graphs.

Cheers to all who helped me sort this out! Aaron

aaron
  • 6,339
  • 12
  • 54
  • 80
  • 1
    Not that the `opts` command has been deprecated in ggplot2 for a while. You should (mostly?) be able to use the code above by replacing `opts` with `theme`. Some element specs like `theme_text` probably need to be changed to `element_text` – Paul 'Joey' McMurdie Mar 30 '14 at 20:17
  • great use of ``'F'`` ;-) – PatrickT Dec 08 '17 at 10:23
11

Have a look at the family argument of theme_text()

dummy <- data.frame(A = rnorm(10), B = rnorm(10))
ggplot(dummy, aes(x = A, y = B)) + geom_point()
#helvetica = default
ggplot(dummy, aes(x = A, y = B)) + geom_point() + opts(axis.title.x = theme_text(family = "sans", face = "bold"))
#times
ggplot(dummy, aes(x = A, y = B)) + geom_point() + opts(axis.title.x = theme_text(family = "serif", face = "bold"))
#courier 
ggplot(dummy, aes(x = A, y = B)) + geom_point() + opts(axis.title.x = theme_text(family = "mono", face = "bold"))
Thierry
  • 18,049
  • 5
  • 48
  • 66
  • 1
    Great, thank you Thierry--that was indeed the way to modify font types using the library of fonts included in R's standard font family library. Not to figure out how to implement custom fonts. Will be looking at some of these other posts... – aaron Nov 05 '10 at 02:15
5

Inspired by a post on kohske's blog I came up with this:

theme_set( theme_bw( base_family= "serif"))

theme_update( panel.grid.minor= theme_blank(),
             panel.grid.major= theme_blank(),
             panel.background= theme_blank(),
             axis.title.x= theme_blank(),
             axis.text.x= theme_text( family= "serif",
               angle= 90, hjust= 1 ),
             axis.text.x= theme_text( family= "serif"),
             axis.title.y= theme_blank())

theme_map <- theme_get()

theme_set( theme_bw())

Now when I want to use that particular theme:

last_plot() + theme_map

YMMV.

BTW, if I had the power I would vote down the preferred answer:

> grid.gedit("GRID.text",gp=gpar(fontfamily="mono"))
Error in editDLfromGPath(gPath, specs, strict, grep, global, redraw) :
  'gPath' (GRID.text) not found

Not sure what this means. Nor was I offered a link to comment on that answer; maybe something has changed on the site.

Community
  • 1
  • 1
Neil Best
  • 817
  • 9
  • 17
  • 1
    Hi Neil, I'm still no expert in ggplot2, but it looks to me like the solution you came up with here works well when using font/theme settings that are natively available to R and ggplot2. I needed to be able to import any custom font from the windows library for my plots, and the solution that Brandon and James helped me come up with works beautifully. Here's how I use grid.gedit: `windowsFonts(F = windowsFont(chartFont))` `grid.gedit("GRID.text",gp=gpar(fontfamily="F"))` You need to make sure that the font family you want is available. – aaron Jul 11 '11 at 15:38
  • @NeilBest The error means that you haven't got any text layers in your plot - ie haven't used `geom_text` – James Jun 22 '12 at 17:14
  • 1
    This no longer seems to work ( at least for me). But a workaround that does work is: `theme_map$text$family = 'new font'` – geotheory Jun 04 '14 at 12:02
2

You can set the font of the labels produced by geom_text with grid.gedit:

grid.gedit("GRID.text",gp=gpar(fontfamily="mono"))

Call this after you have produced your original plot.

James
  • 65,548
  • 14
  • 155
  • 193
  • Great comments, all, thank you so much. Brandon, your suggestion was right on target, except that I am having trouble using the method found at http://johndunavent.com/combined-line-and-bar-chart-ggplot2 to modify geom_text font labels. James, not sure if you're familiar with that post, but how would I use your solution (which worked perfectly) to modify geom_text label fonts with a font that I've brought in to R using the windowsFonts() command? Thanks for all your help! Jeff, will check out Cairo if I keep hitting a brick well here... – aaron Nov 05 '10 at 03:14
  • `windowsFonts(Verdana="TT Verdana")` then you can use `fontfamily="Verdana"`. You may also want to set the axis labels and titles with `"axis.text"` and `"axis.title"` in the first argument. That link is now dead by the way, but you can still get some through the Google cache. – James Apr 21 '11 at 15:12
0

Also check out the Cairo package, which has support for totally switching out all of the fonts with those of your choosing. http://rforge.net/doc/packages/Cairo/00Index.html

Jeff
  • 1,426
  • 8
  • 19
0

This seems like the simplest solution, for my money.

Some play data in df, and made into a simple graph, "p", with nice long x and y labels, so we can see the font change:

df <- data.frame(A = rnorm(10), B = rnorm(10))
p = ggplot(data = df, aes(x = A, y = B)) + geom_point()
p = p + xlab("A long x-string so we can see the effect of the font switch")
p = p + ylab("Likewise up the ordinate")

And we view the default plot in whatever that font is:

p 

Now we switch to Optima, adding some nice title and subtitle to bask in the glory of Optima:

label = "Now we switch to Optima"
subtitle = "Optima is a nice font: https://en.wikipedia.org/wiki/Optima#Usages"

And after all that, we print in the new font

# the only line you need to read:
p + theme(text = element_text(family = "Optima", , face = "bold"))
p = p + ggtitle(label = label, subtitle = subtitle)
p

graph in optima font

tim
  • 3,559
  • 1
  • 33
  • 46
  • 1
    Hey @tim, ggplot2 comes with built-in fonts options. This question deals with situations where you want to import fonts not available in ggplot2 from your system. – aaron Oct 11 '17 at 17:46