r-lib/ragg

Where and why does ragg changes the fonts on Linux systems?

Closed this issue · 2 comments

Hi,

i noticed my plots look differentially when being hosted on shinyapps.io - running a linux system (compared to my local system) and was able to attribute this to the ragg-library.
In some replies to other issues you say "Don't rely just on the font by supplied by the OS as results may look different".
e.g.: #124
However, to me it seems it is not just a Windows (or Mac) vs. Linux but ragg vs. png when on Linx issue.

Here the first attempts to identify the problem:
https://community.rstudio.com/t/plots-on-shinyapps-io-are-rendered-differentially-depending-on-used-libraries/177636/3

You can see it even in your own explanation: https://www.tidyverse.org/blog/2021/02/modern-text-features/
grafik

When looking at the titles, there is not a big difference between Windows - Mac - Linux, but the biggest difference is Linux-Cairo vs. Linux-ragg (more spacing between the letters, less weight - looks more like Plotly).

Also this seems to strongly affect the fontfamily ("symbol") for mathematical expressions, as reported in
#150
#89
#101

In my case the multiplcation symbol of an expression (%%) is not working correctly and just presenting a dot (when being hosted on shinyapps.io and using ragg). Using '' or using '×' is working fine, the same is true for saving plots with device = png or working on windows.

If the font in Linux doesn't support special characters, why is it working without ragg? At which point another font is defined? Is this driven by systemfonts?

Example:

library(ggplot2)
library(ragg)
library(shiny)

# Define UI 
ui <- fluidPage(
    titlePanel("PlotRenderTest"),
    column(width = 6, imageOutput("Plot_png") ),
    column(width = 6, imageOutput("Plot_ragg") )
    )

# Define server logic 
server <- function(input, output) {
  
  # Base Plot
  Plot = reactive({
    ggplot(data = data.frame(x = c(1,2,3),
                             y = c(30, 10, 20)),
           aes(x = x, y = y)) + 
      geom_col() + theme_bw(base_size = 14) +
      scale_x_continuous(labels = c(parse(text = "1*'*'*10"),
                                    parse(text = "2%*%10"),
                                    parse(text = "3*'×'*10")),
                         breaks = c(1,2,3))
  })

    # save plot as png
  output$Plot_png = renderImage({
    ggsave("Plot.png",
           device = png, 
      plot = Plot() + labs(title = "device = png"),
      bg = "white", dpi = 96, width=15, height = 13, units = "cm")

    # Return the filename for the download function 
    list(src = "Plot.png", contentType = 'image/png')
  }, deleteFile = FALSE)
  
  # save plot as ragg-png, 
  output$Plot_ragg = renderImage({
    ggsave("Plot_ragg.png",
           plot = Plot() + labs(title = "device = ragg"),
           bg = "white", dpi = 96, width=15, height = 13, units = "cm")

  # Return the filename for the download function 
    list(src = "Plot_ragg.png", contentType = 'image/png')
  }, deleteFile = FALSE)
}

# Run the application 
shinyApp(ui = ui, server = server)

On Windows:
grafik

On shinyapps.io:
grafik

Summary:
ragg on Linux (shinyapps.io) - different font, looks like plotly, special characters are sometimes broken.
Linux without ragg - very similar to visual appearence in other operating systems.

So, there seems to be two things in this issue (correct me if I'm wrong)

  1. rendering of text. You compare ragg to cairo and find that it looks slightly different in positioning and weight. This is expected. Cairo is not the gold standard of text rendering and I have chosen a rendering I find looks correct and good

  2. selecting of glyphs. ragg sometimes (often exclusively on Linux) does not find the expected glyphs to render. Often this is related to using the default symbol font. ragg uses systemfonts for glyph look-up which in turn asks Linux which font is set to handle symbols (through font-config). This is pretty idiomatic to how my thinking with systemfonts is. Let the device use system settings. Again, cairo does not use systemfonts but has its own way of looking up fonts (which again has nothing to do with R or any of the other devices). My guess is that cairo through many years of fine tuned heuristics sometimes aren't using the Linux system setup, but I wouldn't know. The "fix" is in any regard to set a different symbol font (either at the system level with font-config or at the R session level using systemfonts)

Yes, correctly this is what I meant, and I agree, the rendering on Linux looks good.
As I found the biggest differences in Linux + ragg I thought it might be related to ragg, e.g. instead referring to the "Symbol" font you use the "Synbol" font that doesn't exist. That's why I put a question mark at the end.

When you say you follow a strategy that is logical (to you) and Cairo does the unexpected things, I have to believe that.
And at least I know now what to do: either define the fonts on my own or avoid the special characters whenever possible, e.g by using the multiplication sign directly (as in example 3).

Thanks for the response!