rggplot2ggiraph

Why can I not use a system font that is recognized by ggplot2 in ggiraph?


I'm trying to create an interactive plot with ggiraph using my organization's ggplot theme. The fonts specified there are as follows:

font_light <- "Segoe UI Semilight"

The theme uses the fonts this way:

# font_import() # did this once
loadfonts(device = "win") # do this every session

theme_org <- function() {
   theme(
      # Text Elements
      plot.subtitle = element_text(
        family = font_light,
        size = 11,
        hjust = 0,
        margin = margin(b = 10)
      )
   )

When I use this theme to produce a regular ggplot there is no issue. But when I use that ggplot object in a girafe() call I get the following error:

Error in `girafe()`:
! Font family 'Segoe UI Semilight' has not been found on your system or is not registered.
ℹ You can use a google font with `gdtools::register_gfont()`.
ℹ You can use any font with `systemfonts::register_font()`.

Here's what my Segoe system fonts look like:

> systemfonts::system_fonts() %>% filter(grepl("Segoe", family))
# A tibble: 20 × 9
   path                                index name                    family            style     weight width italic monospace
   <chr>                               <int> <chr>                   <chr>             <chr>     <ord>  <ord> <lgl>  <lgl>    
 1 "C:\\Windows\\Fonts\\segmdl2.ttf"       0 SegoeMDL2Assets         Segoe MDL2 Assets Regular   normal norm… FALSE  FALSE    
 2 "C:\\Windows\\Fonts\\segoepr.ttf"       0 SegoePrint              Segoe Print       Regular   normal norm… FALSE  FALSE    
 3 "C:\\Windows\\Fonts\\segoeprb.ttf"      0 SegoePrint-Bold         Segoe Print       Bold      bold   norm… FALSE  FALSE    
 4 "C:\\Windows\\Fonts\\segoesc.ttf"       0 SegoeScript             Segoe Script      Regular   normal norm… FALSE  FALSE    
 5 "C:\\Windows\\Fonts\\segoescb.ttf"      0 SegoeScript-Bold        Segoe Script      Bold      bold   norm… FALSE  FALSE    
 6 "C:\\Windows\\Fonts\\segoeui.ttf"       0 SegoeUI                 Segoe UI          Regular   normal norm… FALSE  FALSE    
 7 "C:\\Windows\\Fonts\\seguibl.ttf"       0 SegoeUIBlack            Segoe UI          Black     heavy  norm… FALSE  FALSE    
 8 "C:\\Windows\\Fonts\\seguibli.ttf"      0 SegoeUIBlack-Italic     Segoe UI          Black It… heavy  norm… TRUE   FALSE    
 9 "C:\\Windows\\Fonts\\segoeuib.ttf"      0 SegoeUI-Bold            Segoe UI          Bold      bold   norm… FALSE  FALSE    
10 "C:\\Windows\\Fonts\\segoeuiz.ttf"      0 SegoeUI-BoldItalic      Segoe UI          Bold Ita… bold   norm… TRUE   FALSE    
11 "C:\\Windows\\Fonts\\seguiemj.ttf"      0 SegoeUIEmoji            Segoe UI Emoji    Regular   normal norm… FALSE  FALSE    
12 "C:\\Windows\\Fonts\\seguihis.ttf"      0 SegoeUIHistoric         Segoe UI Historic Regular   normal norm… FALSE  FALSE    
13 "C:\\Windows\\Fonts\\segoeuii.ttf"      0 SegoeUI-Italic          Segoe UI          Italic    normal norm… TRUE   FALSE    
14 "C:\\Windows\\Fonts\\segoeuil.ttf"      0 SegoeUI-Light           Segoe UI          Light     light  norm… FALSE  FALSE    
15 "C:\\Windows\\Fonts\\seguili.ttf"       0 SegoeUI-LightItalic     Segoe UI          Light It… light  norm… TRUE   FALSE    
16 "C:\\Windows\\Fonts\\seguisb.ttf"       0 SegoeUI-Semibold        Segoe UI          Semibold  semib… norm… FALSE  FALSE    
17 "C:\\Windows\\Fonts\\seguisbi.ttf"      0 SegoeUI-SemiboldItalic  Segoe UI          Semibold… semib… norm… TRUE   FALSE    
18 "C:\\Windows\\Fonts\\segoeuisl.ttf"     0 SegoeUI-Semilight       Segoe UI          Semilight NA     norm… FALSE  FALSE    
19 "C:\\Windows\\Fonts\\seguisli.ttf"      0 SegoeUI-SemilightItalic Segoe UI          Semiligh… NA     norm… TRUE   FALSE    
20 "C:\\Windows\\Fonts\\seguisym.ttf"      0 SegoeUISymbol           Segoe UI Symbol   Regular   normal norm… FALSE  FALSE 

Any advice would be greatly appreciated!

I've read the discussion here but it doesn't seem to apply to my situation. I've tried registering the font but it seems like ggplot and ggiraph are reading the family name differently.

EDIT ---

The answer provided by stefan worked perfectly for Segoe UI Semibold but not for Segoe UI Semilight for some reason. Here's my code:

# register fonts
fonts <- systemfonts::system_fonts()
segoe_fonts <- fonts %>% filter(grepl("Segoe", family))

font_light <- "Segoe UI Semilight"
font_semi <- "Segoe UI Semibold"

font_light_info <- segoe_fonts %>% filter(name == "SegoeUI-Semilight")
font_semi_info <- segoe_fonts %>% filter(name == "SegoeUI-Semibold")

systemfonts::register_font(
  font_light,
  plain = list(font_light_info$path, font_light_info$index)
)
systemfonts::register_font(
  font_semi,
  plain = list(font_semi_info$path, font_semi_info$index)
)

And here's what the output looks like: girafe chart with a subtitle in the default font The subtitle reverts to a default font but the legend title is changed to Semibold. Any ideas?


Solution

  • I don't have "Segoe UI" installed on my system (running on a Mac) so I use "Roboto Light" for the reprex.

    Let's first reproduce your issue based on the default example from ggiraph. First, as in your case the "Roboto" family encompasses multiple fonts or styles. Now, using "Roboto Light" in ggplot2 I get a plot with the correct font. However, I get an error when converting to an interactive plot using girafe().

    library(ggplot2)
    library(ggiraph)
    
    font_light <- "Roboto Light"
    
    fonts <- systemfonts::system_fonts()
    
    fonts[grepl("^Roboto", fonts$family), c("path", "index", "name", "family", "style")] |> 
      transform(path = basename(path))
    #>                       path index                name family         style
    #> 1  Roboto-MediumItalic.ttf     0 Roboto-MediumItalic Roboto Medium Italic
    #> 2   Roboto-BlackItalic.ttf     0  Roboto-BlackItalic Roboto  Black Italic
    #> 3         Roboto-Light.ttf     0        Roboto-Light Roboto         Light
    #> 4          Roboto-Bold.ttf     0         Roboto-Bold Roboto          Bold
    #> 5        Roboto-Italic.ttf     0       Roboto-Italic Roboto        Italic
    #> 6   Roboto-LightItalic.ttf     0  Roboto-LightItalic Roboto  Light Italic
    #> 7       Roboto-Regular.ttf     0      Roboto-Regular Roboto       Regular
    #> 8    Roboto-BoldItalic.ttf     0   Roboto-BoldItalic Roboto   Bold Italic
    #> 9        Roboto-Medium.ttf     0       Roboto-Medium Roboto        Medium
    #> 10        Roboto-Black.ttf     0        Roboto-Black Roboto         Black
    #> 11         Roboto-Thin.ttf     0         Roboto-Thin Roboto          Thin
    #> 12   Roboto-ThinItalic.ttf     0   Roboto-ThinItalic Roboto   Thin Italic
    
    theme_org <- function() {
      theme(
        plot.subtitle = element_text(
          family = font_light,
          size = 11,
          hjust = 0,
          margin = margin(b = 10)
        )
      )
    }
    
    data <- mtcars
    data$carname <- row.names(data)
    
    gg_point <- ggplot(data = data) +
      geom_point_interactive(aes(
        x = wt, y = qsec, color = disp,
        tooltip = carname, data_id = carname
      )) +
      labs(
        title = "Number of cars by cyl",
        subtitle = "Number of cars by cyl"
      ) +
      theme_org()
    
    gg_point
    

    
    girafe(ggobj = gg_point)
    #> Error in `girafe()`:
    #> ! Font family 'Roboto Light' has not been found on your system or is not
    #>   registered.
    #> ℹ You can use a google font with `gdtools::register_gfont()`.
    #> ℹ You can use any font with `systemfonts::register_font()`.
    

    But that could be fixed by registering the font using systemfonts::register_font before running girafe(), where I pass a list containing the path to the desired font with name "Roboto-Light" and the index to the plain= argument like so:

    Note: For the example the index is not needed, i.e. plain = font_light_info$path would be sufficient, but it is required if the font file contains multiple fonts.

    # Register font
    
    font_light_info <- fonts[fonts$name == "Roboto-Light", ]
    systemfonts::register_font(
      font_light, 
      plain = list(font_light_info$path, font_light_info$index)
    )
    
    girafe(ggobj = gg_point)