plotly.R icon indicating copy to clipboard operation
plotly.R copied to clipboard

Can not use my custom font with plotly

Open fnavarro94 opened this issue 2 years ago • 1 comments

I am trying to use a custom font with plotly but it does not work althoug it does work with ggplot. Is there a way to solve this? You can download the font here: https://freefontsfamily.com/proxima-nova-font-family-free-download/

This is the ggplot example that does work:

library(dplyr)
library(ggplot2)
library(plotly)
library(showtext)
font.add("Proxima Nova", "ProximaNova.otf")


df <- data.frame(x = c(1,2,3), y = c(2,3,4))

my_theme_ggplot <-
    ggplot2::theme_bw() +
    ggplot2::theme(
      plot.title = element_text(hjust = 0.5),
      text=element_text(size=16,  family="Proxima Nova")
      )

p <- df %>% ggplot(aes(x = x, y = y)) + 
  geom_line() +
  ggtitle("Title", ) +
  labs(y= "Date", x = "Y Data") +
  my_theme_ggplot

p

This is the plotly example that does not work

df <- data.frame(x = c(1,2,3), y = c(2,3,4))
t <- list(
  family = "Proxima Nova",
  size = 14)

p <- df %>% ggplot(aes(x = x, y = y)) + 
  geom_line() +
  ggtitle("Title", ) +
  labs(y= "Date", x = "Y Data") 

ggplotly(p) %>% layout(font=t)

fnavarro94 avatar Apr 04 '22 20:04 fnavarro94

I saw you were able to get a solution to this specific problem on the RStudio community page; however, I wanted to add something further to the issue and the solution that I was able to find in case others come looking for it.

Working in just plotly (without ggplotly), the issue persists regardless of using showtext_auto().

For example, recoding your example from plotly alone and using a google font for reproducibility, we expect a script font but get a serif font instead.

library(dplyr)
library(plotly)
library(showtext)

font_add_google("Gochi Hand", "gochi") #a script font
showtext_auto()

df <- data.frame(x = c(1,2,3), y = c(2,3,4))

p <- plot_ly(
    df,
    type = "scatter",
    mode = "lines",
    x = ~x,
    y = ~y
) %>% 
    layout(
        title = list(text = "Title"), 
        xaxis = list(title = list(text = "Date")), 
        yaxis = list(title = list(text = "Y Data")), 
        font = list(family = "gochi")
    )

p

image

The root cause of the problem is that plotly is missing a dependency which contains the font file for the custom font. The solution is to reference a CSS file or add brief HTML code in an added dependency to a given plotly object.

#get the source url to the font file from google
gochi_file <- showtextdb::google_fonts("Gochi Hand")$regular_url 

#create custom CSS 
gochi_css <- paste0(
  "<style type = 'text/css'>",
    "@font-face { ",
      "font-family: 'gochi'; ", #however you want to refer to it
      "src: url('", gochi_file, "'); ", #file from google
    "}",
  "</style>")

#add the CSS as a dependency for the plotly object
p$dependencies <- c(
  p$dependencies,
  list(
    htmltools::htmlDependency(
      name = "gochi-font", #these  first 3 arguments don't really matter for this use case
      version = "0",  
      src = "",
      head = gochi_css #refer to the custom CSS created
    )
  )
)

p

image

This can also be done for local font files, just use a filepath to the font file in place of the google font URL. Or if you have a package that has a custom css file (including definitions and files for custom fonts) that you would then like to apply to your plotly object:

new_dependency <- htmltools::htmlDependency(
  name = "my-font", #name it whatever
  version = "0.1.0", #and version it whatever
  src = list(file = "www"), #css file location within "inst" of the package (usually www or inst)
  stylesheet = "custom.css",
  package = "aPackageName",
  all_files = TRUE #needs to be true if aPackageName has the font files you need within the src directory
)
p$dependencies <- c(p$dependencies, list(new_dependency))

cttnguyen avatar Dec 07 '22 15:12 cttnguyen