Search code examples
rggplot2iconsggtextshowtext

How to add icons to ggplot captions and titles?


Right now I am trying to put icons in ggplot visualizations. To this end, I have checked a couple of tutorials on the web and when I run the following code example of Claus Wilke,

library(ggtext)
library(ggplot2)

ggplot(mtcars) +
  aes(mpg, disp) +
  geom_point() +
  labs(title = "This font is awesome:
       <span style='font-family: \"Font Awesome 6 Free Solid\"'>&#62766; &#62650; &#62577;</span>") +
  theme(plot.title = element_markdown())

everything seems fine as you can see in the following result

enter image description here

However, to imitate this code for another visualization of mine, let's say the last week's TidyTuesday challenge of Babynames data, I am using the following code,

library(ggplot2)
library(ggtext)
library(tidyverse)
library(showtext)
library(ggrepel)


font_add_google("Martel", family = "title")
font_add_google("Libre Caslon Display", family = "subtitle")
font_add_google("Space Mono", family = "axis")
font_add_google("Spartan", family = "caption")

showtext_auto()

tuesdata <- tidytuesdayR::tt_load('2022-03-22')
babynames <- tuesdata$babynames


babynames %>%
  group_by(year) %>%
  top_n(1, n) %>%
  ggplot(aes(x = year, y = prop)) +
  geom_step(size = 0.5, show.legend = FALSE, direction = "hv") +
  theme_bw() +
  labs(x = "Year", 
       y = "Proportion",
       title = "How Unique are Names in the United States?",
       subtitle = "This visualization illustrates the proportion of most given baby names in that year between 1880 and 2017",
       caption = "Source: {babynames} package | Plot: <span style='font-family: \"Font Awesome 6 Brands\"'>&#xf09b;</span> muhammetozkrca | TidyTuesday-Week 12") +
  background_grid(major = 'none', minor = "none") +
  theme(
    plot.title = element_text(hjust = 0.5, family = "title", size = 20),
    plot.subtitle = element_markdown(hjust = 0.5, family = "subtitle", size = 14), # note that to color numbers differently, I used element_markdown not element_text function
    plot.caption = element_markdown(hjust = 0.5, size = 7),
    legend.position = c(0.9, 0.6),
    legend.justification = "center",
    legend.title = element_text(family = "caption", hjust = 1, vjust = 0.7),
    legend.title.align = 0.5,
    axis.title.x = element_text(family = "axis"),
    axis.title.y = element_text(family = "axis"),
    panel.border = element_blank(),
    axis.ticks = element_blank())

and I received this error

Error in grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y,  : 
  polygon edge not found

Sometimes, I also receive this error as well

In grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y,  :
  font family 'Font Awesome 6 Free Solid' not found, will use 'wqy-microhei' instead

To sum up, I do not really understand what's going on. When I searched similar inquiries, I saw that the problem is mostly due to the fact that users do not have font files on their pc. Yet, if this would be the problem for me, I do not think that I can reproduce Wilke's example. Therefore, if you can assist me in solving this problem, I will be grateful for that. Thank you in advance.


Solution

  • The issue is that you use showtext for the text rendering. Doing so requires to add local fonts via font_add so that they could be used in the plot:

    library(ggplot2)
    library(ggtext)
    library(showtext)
    #> Loading required package: sysfonts
    #> Loading required package: showtextdb
    library(ggrepel)
    library(cowplot)
    
    font_add_google("Martel", family = "title")
    font_add_google("Libre Caslon Display", family = "subtitle")
    font_add_google("Space Mono", family = "axis")
    font_add_google("Spartan", family = "caption")
    
    fa_path <- systemfonts::font_info(family = "Font Awesome 6 Brands Regular")[["path"]]
    font_add(family = "fa-brands", regular = fa_path)
    
    showtext_auto()
    
    ggplot(babynames, aes(x = year, y = prop)) +
      geom_step(size = 0.5, show.legend = FALSE, direction = "hv") +
      theme_bw() +
      labs(
        x = "Year",
        y = "Proportion",
        title = "How Unique are Names in the United States?",
        subtitle = "This visualization illustrates the proportion of most given baby names in that year between 1880 and 2017",
        caption = "Source: {babynames} package | Plot: <span style='font-family: \"fa-brands\"'>&#xf09b;</span> muhammetozkrca | TidyTuesday-Week 12"
      ) +
      background_grid(major = "none", minor = "none") +
      theme(
        plot.title = element_text(hjust = 0.5, family = "title", size = 20),
        plot.subtitle = element_markdown(hjust = 0.5, family = "subtitle", size = 14),
        plot.caption = element_markdown(hjust = 0.5, size = 14),
        legend.position = c(0.9, 0.6),
        legend.justification = "center",
        legend.title = element_text(family = "caption", hjust = 1, vjust = 0.7),
        legend.title.align = 0.5,
        axis.title.x = element_text(family = "axis"),
        axis.title.y = element_text(family = "axis"),
        panel.border = element_blank(),
        axis.ticks = element_blank()
      )
    

    DATA

    babynames <- structure(list(
      X = c(
        875979L, 895453L, 915066L, 934495L, 954004L,
        973836L, 994240L, 1015321L, 1037346L, 1060379L, 1084841L, 1109784L,
        1135041L, 1160654L, 1186574L, 1212571L, 1238789L, 1265481L, 1292890L,
        1321132L, 1350394L, 1380480L, 1410860L, 1441772L, 1473351L, 1505753L,
        1539167L, 1573759L, 1608606L, 1623219L, 1657921L, 1691988L, 1725891L,
        1759623L, 1792892L, 1826120L, 1859218L, 1892197L
      ), year = 1980:2017,
      sex = c(
        "M", "M", "M", "M", "M", "M", "M", "M", "M", "M",
        "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M",
        "M", "M", "M", "M", "M", "M", "M", "F", "F", "F", "F", "F",
        "F", "F", "F", "F"
      ), name = c(
        "Michael", "Michael", "Michael",
        "Michael", "Michael", "Michael", "Michael", "Michael", "Michael",
        "Michael", "Michael", "Michael", "Michael", "Michael", "Michael",
        "Michael", "Michael", "Michael", "Michael", "Jacob", "Jacob",
        "Jacob", "Jacob", "Jacob", "Jacob", "Jacob", "Jacob", "Jacob",
        "Jacob", "Isabella", "Isabella", "Sophia", "Sophia", "Sophia",
        "Emma", "Emma", "Emma", "Emma"
      ), n = c(
        68693L, 68765L, 68228L,
        67995L, 67736L, 64906L, 64205L, 63647L, 64133L, 65382L, 65282L,
        60785L, 54386L, 49550L, 44470L, 41402L, 38365L, 37548L, 36614L,
        35361L, 34471L, 32541L, 30568L, 29630L, 27879L, 25830L, 24841L,
        24273L, 22591L, 22298L, 22905L, 21837L, 22304L, 21213L, 20924L,
        20435L, 19471L, 19738L
      ), prop = c(
        0.03703079, 0.03692247,
        0.03615445, 0.0364911, 0.03610228, 0.03373805, 0.03342343,
        0.03264834, 0.03204521, 0.03120182, 0.03034735, 0.0286831,
        0.02591513, 0.02399562, 0.02182099, 0.02058782, 0.01915021,
        0.01879903, 0.01806194, 0.01734789, 0.01651392, 0.01573989,
        0.0147991, 0.01410917, 0.0131991, 0.01214938, 0.01133859,
        0.01096627, 0.0103702, 0.01102237, 0.01169646, 0.011285,
        0.01151924, 0.01102629, 0.01072117, 0.01050471, 0.01009677,
        0.0105275
      )
    ), class = c("grouped_df", "tbl_df", "tbl", "data.frame"), row.names = c(NA, -38L), groups = structure(list(
      year = 1980:2017,
      .rows = structure(list(
        1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L,
        10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, 20L,
        21L, 22L, 23L, 24L, 25L, 26L, 27L, 28L, 29L, 30L, 31L,
        32L, 33L, 34L, 35L, 36L, 37L, 38L
      ), ptype = integer(0), class = c(
        "vctrs_list_of",
        "vctrs_vctr", "list"
      ))
    ), row.names = c(NA, -38L), class = c(
      "tbl_df",
      "tbl", "data.frame"
    ), .drop = TRUE))