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=