The material in this lab may be the least statistical out of all the labs we do, but likely contains the material you’ll use the most. Today, we’ll cover how to customize your ggplots with themes, fonts, and colors.
Part 1: Customizing plots
Themes and color palettes
Two more primers! (well, we might do another one next week)
Changing the font
Note: This section comes from Andrew Heiss’s excellent materials.
You can use theme() to change the fonts as well, though sometimes it’s a little tricky to get R to see the fonts on your computer—especially if you use Windows. This detailed blog post explains how to work with custom fonts in ggplot and shows how to get it set up on Windows. It should Just Work™ on macOS.
In short, as long as you load the fonts correctly, you can specify different fonts either in a complete theme like theme_minimal(base_family = "Comic Sans MS") or in theme() like theme(plot.title = element_text(family = "Papyrus")).
Other places to look for font solutions include the r cookbook and the extrafont package.
Even if you can’t get named fonts working on your computer you should at least have a built-in sans, serif, and mono font within ggplot. Here’s some example code to change the default font to a serif font:
library(palmerpenguins)
ggplot(penguins, aes(y=island, fill = island)) +
geom_bar() +
theme(text = element_text(family = "serif"))

Edit the above code to produce the plot using either a mono family (if you’re having trouble with fonts) or a font of your choice.
Part 2: geom_annotate
We’ve already talked a fair bit about legends and when they’re useful/not useful. annotate allows you to add an “annotation” layer onto your ggplot, which uses arguments that live outside of the other defined datasets and aesthetics. The primer gives you an example of adding a description using annotate, but this geom can also be used as an alternative to a legend.
library(palmerpenguins)
ggplot(penguins, aes(y=island, fill = island)) +
geom_bar() +
theme(text = element_text(family = "serif")) +
annotate("text", # What type of annotation to use
x = c(15, 50, 100), # X positions of annotations
y =c("Torgersen", "Dream", "Biscoe"), # Y positions of annotations (weird because this is a barchart)
label =c("Torgersen", "Dream", "Biscoe")) + # Labels for annotations
theme(legend.position = "none") # Gets rid of the legend

Edit the above code to produce the plot with annotations in a different place (or completely change the annotation!)
Part 3: Open-ended
Choose 3 graphs from this week and recreate them here, but make them fancy. This should include changing the theme, color palette, and font. You can absolutely use the same customization for all 3, as long as it’s appropriate for all of them. If you’re feeling ambitious, try designing each of the 3 using different customizations! You should choose at most 2 maps, and you can also use ggplots from class (like the penguins data) or from the primers.
Bonus round
If you find yourself saying “I really wish I could remove some of these axis labels” or “This plot would look better with a bright green background”, I recommend taking a look at Andrew Heiss’s lesson on ggplot2 themes. For the most part, the standard ggplot2 themes get the job done, but this might come in handy when there’s something super specific you want to change.
LS0tCnRpdGxlOiAiTGFiMDQ6IEN1c3RvbWl6YXRpb24iCm91dHB1dDogCiAgaHRtbF9kb2N1bWVudDogCiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgY3NzOiBzdGF0NDEtbGFiLXRoZW1lLmNzcwotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKYGBgCgpUaGUgbWF0ZXJpYWwgaW4gdGhpcyBsYWIgbWF5IGJlIHRoZSAqbGVhc3QqIHN0YXRpc3RpY2FsIG91dCBvZiBhbGwgdGhlIGxhYnMgd2UgZG8sIGJ1dCBsaWtlbHkgY29udGFpbnMgdGhlIG1hdGVyaWFsIHlvdSdsbCB1c2UgdGhlIG1vc3QuIFRvZGF5LCB3ZSdsbCBjb3ZlciBob3cgdG8gY3VzdG9taXplIHlvdXIgYGdncGxvdHNgIHdpdGggdGhlbWVzLCBmb250cywgYW5kIGNvbG9ycy4gCgojIFBhcnQgMTogQ3VzdG9taXppbmcgcGxvdHMKCiMjIFRoZW1lcyBhbmQgY29sb3IgcGFsZXR0ZXMKClR3byBtb3JlIHByaW1lcnMhICh3ZWxsLCB3ZSBtaWdodCBkbyBhbm90aGVyIG9uZSBuZXh0IHdlZWspCiAKICsgW092ZXJwbG90dGluZyBhbmQgYmlnIGRhdGFdKGh0dHBzOi8vcnN0dWRpby5jbG91ZC9sZWFybi9wcmltZXJzLzMuNykKICsgW0N1c3RvbWl6ZSBwbG90c10oaHR0cHM6Ly9yc3R1ZGlvLmNsb3VkL2xlYXJuL3ByaW1lcnMvMy44KQoKCiMjIENoYW5naW5nIHRoZSBmb250CgoqTm90ZSo6IFRoaXMgc2VjdGlvbiBjb21lcyBmcm9tIFtBbmRyZXcgSGVpc3Mnc10oaHR0cHM6Ly93d3cuYW5kcmV3aGVpc3MuY29tKSBleGNlbGxlbnQgbWF0ZXJpYWxzLiAKCllvdSBjYW4gdXNlIGB0aGVtZSgpYCB0byBjaGFuZ2UgdGhlIGZvbnRzIGFzIHdlbGwsIHRob3VnaCBzb21ldGltZXMgaXTigJlzIGEgbGl0dGxlIHRyaWNreSB0byBnZXQgUiB0byBzZWUgdGhlIGZvbnRzIG9uIHlvdXIgY29tcHV0ZXLigJRlc3BlY2lhbGx5IGlmIHlvdSB1c2UgV2luZG93cy4gVGhpcyBbZGV0YWlsZWQgYmxvZyBwb3N0XShodHRwczovL3d3dy5hbmRyZXdoZWlzcy5jb20vYmxvZy8yMDE3LzA5LzI3L3dvcmtpbmctd2l0aC1yLWNhaXJvLWdyYXBoaWNzLWN1c3RvbS1mb250cy1hbmQtZ2dwbG90LykgZXhwbGFpbnMgaG93IHRvIHdvcmsgd2l0aCBjdXN0b20gZm9udHMgaW4gZ2dwbG90IGFuZCBzaG93cyBob3cgdG8gZ2V0IGl0IHNldCB1cCBvbiBXaW5kb3dzLiBJdCBzaG91bGQgSnVzdCBXb3Jr4oSiIG9uIG1hY09TLgoKSW4gc2hvcnQsIGFzIGxvbmcgYXMgeW91IGxvYWQgdGhlIGZvbnRzIGNvcnJlY3RseSwgeW91IGNhbiBzcGVjaWZ5IGRpZmZlcmVudCBmb250cyBlaXRoZXIgaW4gYSBjb21wbGV0ZSB0aGVtZSBsaWtlIGB0aGVtZV9taW5pbWFsKGJhc2VfZmFtaWx5ID0gIkNvbWljIFNhbnMgTVMiKWAgb3IgaW4gYHRoZW1lKClgIGxpa2UgYHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFtaWx5ID0gIlBhcHlydXMiKSlgLgoKT3RoZXIgcGxhY2VzIHRvIGxvb2sgZm9yIGZvbnQgc29sdXRpb25zIGluY2x1ZGUgdGhlIFtyIGNvb2tib29rXShodHRwOi8vd3d3LmNvb2tib29rLXIuY29tL0dyYXBocy9Gb250cy8pIGFuZCB0aGUgW2BleHRyYWZvbnRgXShodHRwczovL2dpdGh1Yi5jb20vd2NoL2V4dHJhZm9udCkgcGFja2FnZS4gCgoqKkV2ZW4gaWYgeW91IGNhbid0IGdldCBuYW1lZCBmb250cyB3b3JraW5nIG9uIHlvdXIgY29tcHV0ZXIqKiB5b3Ugc2hvdWxkIGF0IGxlYXN0IGhhdmUgYSBidWlsdC1pbiAqc2FucyosICpzZXJpZiosIGFuZCAqbW9ubyogZm9udCB3aXRoaW4gZ2dwbG90LiBIZXJlJ3Mgc29tZSBleGFtcGxlIGNvZGUgdG8gY2hhbmdlIHRoZSBkZWZhdWx0IGZvbnQgdG8gYSAqc2VyaWYqIGZvbnQ6IAoKYGBge3J9CmxpYnJhcnkocGFsbWVycGVuZ3VpbnMpCmdncGxvdChwZW5ndWlucywgYWVzKHk9aXNsYW5kLCBmaWxsID0gaXNsYW5kKSkgKyAKICBnZW9tX2JhcigpICsgCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAic2VyaWYiKSkKYGBgCgpFZGl0IHRoZSBhYm92ZSBjb2RlIHRvIHByb2R1Y2UgdGhlIHBsb3QgdXNpbmcgKmVpdGhlciogYSBgbW9ub2AgZmFtaWx5IChpZiB5b3UncmUgaGF2aW5nIHRyb3VibGUgd2l0aCBmb250cykgb3IgYSBmb250IG9mIHlvdXIgY2hvaWNlLiAKCiMgUGFydCAyOiBgZ2VvbV9hbm5vdGF0ZWAKCldlJ3ZlIGFscmVhZHkgdGFsa2VkIGEgZmFpciBiaXQgYWJvdXQgbGVnZW5kcyBhbmQgd2hlbiB0aGV5J3JlIHVzZWZ1bC9ub3QgdXNlZnVsLiBbYGFubm90YXRlYF0oaHR0cHM6Ly9nZ3Bsb3QyLnRpZHl2ZXJzZS5vcmcvcmVmZXJlbmNlL2Fubm90YXRlLmh0bWwpIGFsbG93cyB5b3UgdG8gYWRkIGFuICJhbm5vdGF0aW9uIiBsYXllciBvbnRvIHlvdXIgZ2dwbG90LCB3aGljaCB1c2VzIGFyZ3VtZW50cyB0aGF0IGxpdmUgb3V0c2lkZSBvZiB0aGUgb3RoZXIgZGVmaW5lZCBkYXRhc2V0cyBhbmQgYWVzdGhldGljcy4gVGhlIHByaW1lciBnaXZlcyB5b3UgYW4gZXhhbXBsZSBvZiBhZGRpbmcgYSBkZXNjcmlwdGlvbiB1c2luZyBgYW5ub3RhdGVgLCBidXQgdGhpcyBnZW9tIGNhbiBhbHNvIGJlIHVzZWQgYXMgYW4gYWx0ZXJuYXRpdmUgdG8gYSBsZWdlbmQuIAoKYGBge3J9CmxpYnJhcnkocGFsbWVycGVuZ3VpbnMpCmdncGxvdChwZW5ndWlucywgYWVzKHk9aXNsYW5kLCBmaWxsID0gaXNsYW5kKSkgKyAKICBnZW9tX2JhcigpICsgCiAgdGhlbWUodGV4dCA9IGVsZW1lbnRfdGV4dChmYW1pbHkgPSAic2VyaWYiKSkgKwogIGFubm90YXRlKCJ0ZXh0IiwgIyBXaGF0IHR5cGUgb2YgYW5ub3RhdGlvbiB0byB1c2UgCiAgICAgICAgICAgeCA9IGMoMTUsIDUwLCAxMDApLCAjIFggcG9zaXRpb25zIG9mIGFubm90YXRpb25zCiAgICAgICAgICAgeSA9YygiVG9yZ2Vyc2VuIiwgIkRyZWFtIiwgIkJpc2NvZSIpLCAjIFkgcG9zaXRpb25zIG9mIGFubm90YXRpb25zICh3ZWlyZCBiZWNhdXNlIHRoaXMgaXMgYSBiYXJjaGFydCkKICAgICAgICAgICBsYWJlbCA9YygiVG9yZ2Vyc2VuIiwgIkRyZWFtIiwgIkJpc2NvZSIpKSArICMgTGFiZWxzIGZvciBhbm5vdGF0aW9ucyAKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICMgR2V0cyByaWQgb2YgdGhlIGxlZ2VuZCAKYGBgCgpFZGl0IHRoZSBhYm92ZSBjb2RlIHRvIHByb2R1Y2UgdGhlIHBsb3Qgd2l0aCBhbm5vdGF0aW9ucyBpbiBhIGRpZmZlcmVudCBwbGFjZSAob3IgY29tcGxldGVseSBjaGFuZ2UgdGhlIGFubm90YXRpb24hKSAKCiMgUGFydCAzOiBPcGVuLWVuZGVkCgpDaG9vc2UgMyBncmFwaHMgZnJvbSB0aGlzIHdlZWsgYW5kIHJlY3JlYXRlIHRoZW0gaGVyZSwgYnV0IG1ha2UgdGhlbSAqZmFuY3kqLiBUaGlzIHNob3VsZCBpbmNsdWRlIGNoYW5naW5nIHRoZSB0aGVtZSwgY29sb3IgcGFsZXR0ZSwgYW5kIGZvbnQuIFlvdSBjYW4gYWJzb2x1dGVseSB1c2UgdGhlIHNhbWUgY3VzdG9taXphdGlvbiBmb3IgYWxsIDMsIGFzIGxvbmcgYXMgaXQncyBhcHByb3ByaWF0ZSBmb3IgYWxsIG9mIHRoZW0uIElmIHlvdSdyZSBmZWVsaW5nIGFtYml0aW91cywgdHJ5IGRlc2lnbmluZyBlYWNoIG9mIHRoZSAzIHVzaW5nIGRpZmZlcmVudCBjdXN0b21pemF0aW9ucyEgWW91IHNob3VsZCBjaG9vc2UgYXQgbW9zdCAyIG1hcHMsIGFuZCB5b3UgY2FuIGFsc28gdXNlIGBnZ3Bsb3RzYCBmcm9tIGNsYXNzIChsaWtlIHRoZSBgcGVuZ3VpbnNgIGRhdGEpIG9yIGZyb20gdGhlIHByaW1lcnMuIAoKIyMgQm9udXMgcm91bmQKCklmIHlvdSBmaW5kIHlvdXJzZWxmIHNheWluZyAiSSByZWFsbHkgd2lzaCBJIGNvdWxkIHJlbW92ZSBzb21lIG9mIHRoZXNlIGF4aXMgbGFiZWxzIiBvciAiVGhpcyBwbG90IHdvdWxkIGxvb2sgYmV0dGVyIHdpdGggYSBicmlnaHQgZ3JlZW4gYmFja2dyb3VuZCIsIEkgcmVjb21tZW5kIHRha2luZyBhIGxvb2sgYXQgQW5kcmV3IEhlaXNzJ3MgW2xlc3NvbiBvbiBnZ3Bsb3QyIHRoZW1lc10oaHR0cHM6Ly9kYXRhdml6bTIwLmNsYXNzZXMuYW5kcmV3aGVpc3MuY29tL2xlc3Nvbi8wNS1sZXNzb24vKS4gRm9yIHRoZSBtb3N0IHBhcnQsIHRoZSBzdGFuZGFyZCBgZ2dwbG90MmAgdGhlbWVzIGdldCB0aGUgam9iIGRvbmUsIGJ1dCB0aGlzIG1pZ2h0IGNvbWUgaW4gaGFuZHkgd2hlbiB0aGVyZSdzIHNvbWV0aGluZyBzdXBlciBzcGVjaWZpYyB5b3Ugd2FudCB0byBjaGFuZ2UuCgo=