Search code examples
rpdfggplot2purrrplotmath

Error when exporting ggplot graphs to pdf: invalid font type


I'm having trouble getting my plots to save using ggsave(). I keep getting this error:

Error in grid.Call.graphics(C_text, as.graphicsAnnot(x$label), x$x, x$y, : invalid font type

I don't understand why I would be getting this error.. I'm not using any special type of font. I looked at these similar questions:

But they haven't worked for me. The code works fine and the plots print perfectly in Rstudio!

Sample Data:

final_df<-structure(list(orgid_sc = c("USGS-NJ", "USGS-NJ", "USGS-NJ", 
"USGS-NJ", "USGS-NJ", "USGS-NJ", "USGS-NJ", "USGS-NJ", "USGS-NJ", 
"21NJDEP1"), locid = c("USGS-01396030", "USGS-01396030", "USGS-01396030", 
"USGS-01396030", "USGS-01378560", "USGS-01378560", "USGS-01378560", 
"USGS-01378560", "USGS-01393400", "21NJDEP1-01396030"), stdate = structure(c(11359, 
11359, 11359, 11359, 16498, 16498, 16498, 16498, 12149, 12437
), class = "Date"), sttime = structure(c(34200, 34200, 34200, 
34200, 50400, 50400, 50400, 50400, 80280, 35700), class = c("hms", 
"difftime"), units = "secs"), Specific_conductance = c(7450, 
7450, 7300, 7300, 7190, 7190, 6960, 6960, 6080, 5550), valunit_sc = c("uS/cm @25C", 
"uS/cm @25C", "uS/cm @25C", "uS/cm @25C", "uS/cm @25C", "uS/cm @25C", 
"uS/cm @25C", "uS/cm @25C", "uS/cm @25C", "uS/cm @25C"), swqs_sc = c("FW2-NT", 
"FW2-NT", "FW2-NT", "FW2-NT", "FW2-NT", "FW2-NT", "FW2-NT", "FW2-NT", 
"FW2-NT", "FW2-NT"), WMA_sc = c(7L, 7L, 7L, 7L, 5L, 5L, 5L, 5L, 
7L, 7L), year_sc = c(2001L, 2001L, 2001L, 2001L, 2015L, 2015L, 
2015L, 2015L, 2003L, 2004L), locid2 = c("01396030", "01396030", 
"01396030", "01396030", "01378560", "01378560", "01378560", "01378560", 
"01393400", "01396030"), HUC14 = c("HUC02030104050090", "HUC02030104050090", 
"HUC02030104050090", "HUC02030104050090", "HUC02030103180010", 
"HUC02030103180010", "HUC02030103180010", "HUC02030103180010", 
"HUC02030104020020", "HUC02030104050090"), HUC_name = c("Rahway River SB", 
"Rahway River SB", "Rahway River SB", "Rahway River SB", "Coles Brook / Van Saun Mill Brook", 
"Coles Brook / Van Saun Mill Brook", "Coles Brook / Van Saun Mill Brook", 
"Coles Brook / Van Saun Mill Brook", "Elizabeth R (Elizabeth CORP BDY to I-78)", 
"Rahway River SB"), orgid_tds = c("USGS-NJ", "USGS-NJ", "USGS-NJ", 
"USGS-NJ", "USGS-NJ", "USGS-NJ", "USGS-NJ", "USGS-NJ", NA, "21NJDEP1"
), tds = c(3800, 4190, 3800, 4190, 3630, 3900, 3630, 3900, NA, 
3056), valunit_tds = c("mg/L", "mg/L", "mg/L", "mg/L", "mg/L", 
"mg/L", "mg/L", "mg/L", NA, "mg/L"), swqs_tds = c("FW2-NT", "FW2-NT", 
"FW2-NT", "FW2-NT", "FW2-NT", "FW2-NT", "FW2-NT", "FW2-NT", NA, 
"FW2-NT"), WMA_tds = c(7L, 7L, 7L, 7L, 5L, 5L, 5L, 5L, NA, 7L
), year_tds = c(2001L, 2001L, 2001L, 2001L, 2015L, 2015L, 2015L, 
2015L, NA, 2004L), orgid = c("USGS-NJ", "USGS-NJ", "USGS-NJ", 
"USGS-NJ", "USGS-NJ", "USGS-NJ", "USGS-NJ", "USGS-NJ", NA, "21NJDEP1"
), Chloride = c(2230, 2230, 2230, 2230, 2100, 2100, 2100, 2100, 
NA, 1409.3), valunit = c("mg/L", "mg/L", "mg/L", "mg/L", "mg/L", 
"mg/L", "mg/L", "mg/L", NA, "mg/L"), swqs = c("FW2-NT", "FW2-NT", 
"FW2-NT", "FW2-NT", "FW2-NT", "FW2-NT", "FW2-NT", "FW2-NT", NA, 
"FW2-NT"), WMA = c(7L, 7L, 7L, 7L, 5L, 5L, 5L, 5L, NA, 7L), year = c(2001L, 
2001L, 2001L, 2001L, 2015L, 2015L, 2015L, 2015L, NA, 2004L), 
    combo = c("HUC02030104050090 Rahway River SB", "HUC02030104050090 Rahway River SB", 
    "HUC02030104050090 Rahway River SB", "HUC02030104050090 Rahway River SB", 
    "HUC02030103180010 Coles Brook / Van Saun Mill Brook", "HUC02030103180010 Coles Brook / Van Saun Mill Brook", 
    "HUC02030103180010 Coles Brook / Van Saun Mill Brook", "HUC02030103180010 Coles Brook / Van Saun Mill Brook", 
    "HUC02030104020020 Elizabeth R (Elizabeth CORP BDY to I-78)", 
    "HUC02030104050090 Rahway River SB")), .Names = c("orgid_sc", 
"locid", "stdate", "sttime", "Specific_conductance", "valunit_sc", 
"swqs_sc", "WMA_sc", "year_sc", "locid2", "HUC14", "HUC_name", 
"orgid_tds", "tds", "valunit_tds", "swqs_tds", "WMA_tds", "year_tds", 
"orgid", "Chloride", "valunit", "swqs", "WMA", "year", "combo"
), row.names = c(NA, -10L), class = c("tbl_df", "tbl", "data.frame"
))

Code:

formula1 <- y ~ x

correlation_theme<- theme_linedraw()+
  theme(plot.title=element_text(size=15, face="bold",vjust=0.5,hjust = 0.5),
        plot.subtitle = element_text(13,face = "bold",vjust=0.5,hjust=0.5),
        panel.grid.major.x = element_blank(),
        panel.grid.minor.x = element_blank(),
        plot.background = element_blank(),
        panel.background = element_blank(),
        legend.position = c(0.5, 0.2),
        legend.background = element_blank(),
        legend.text=element_text(size=10, face="bold"))

corr_plot_map_way <- function(df, x, y, title,xlab,ylab) {
  x_var <- enquo(x)
  y_var <- enquo(y)

  ggplot(df, aes(x = !!x_var, y = !!y_var)) +
    geom_point(size = 2,alpha=0.5) +
    geom_smooth(method = "lm", se = FALSE,formula=formula1) +
    scale_x_continuous(limits = c(0, 6200), expand = c(0, 0)) +
    scale_y_continuous(limits = c(0, 2000), expand = c(0, 0)) +
    labs(
      title = title,
      #subtitle = paste(rlang::quo_text(x_var), "vs.", rlang::quo_text(y_var),"(1997-2018)"),
      subtitle = paste(xlab, "vs.", ylab,"(1997-2018)"),

      x=xlab,y=ylab)+
    stat_poly_eq(aes(label = paste(..eq.label.., sep = "~~~")), 
                 label.x.npc = 0.8, label.y.npc = 0.9,
                 eq.with.lhs = "italic(hat(y))~`=`~",
                 eq.x.rhs = "~italic(x)",
                 formula = formula1, parse = TRUE, size = 5) +
    stat_poly_eq(aes(label = paste(..rr.label.., sep = "~~~")), 
                 label.x.npc = 0.8, label.y.npc = 0.83,
                 formula = formula1, parse = TRUE, size = 5) +

    correlation_theme
}

nested_by_HUC14 <- 
  final_df %>%
  group_by(combo) %>% 
  nest()

plots<-nested_by_HUC14 %>%
  mutate(plot = map2(data, combo, ~ corr_plot_map_way(.x, Specific_conductance,Chloride, .y,xlab="Specific Conductance(µS/cm)",ylab="Chloride(mg/L)")),filename=paste0(combo,".pdf")) %>%
  select(filename,plot)

map2(paste0(plots$filename,".pdf"),plots$plot,ggsave)

I added all the code, cause I'm not sure what section might be causing this error. Sorry for making it so long!


Solution

  • The main problems were:

    • Special character / in combo which made file names invalid -> use str_replace to replace / with -

    • Special characters in your xlab, ylab, subtitle -> use substitute

    library(rlang)
    library(tidyverse)
    library(ggpmisc)
    
    formula1 <- y ~ x
    
    corr_plot_map_way <- function(df, x, y, title, xlab, ylab) {
      x_var <- enquo(x)
      y_var <- enquo(y)
    
      ggplot(df, aes(x = !!x_var, y = !!y_var)) +
        geom_point(size = 2, alpha = 0.5) +
        geom_smooth(method = "lm", se = FALSE, formula = formula1) +
        scale_x_continuous(limits = c(0, 6200), expand = c(0, 0)) +
        scale_y_continuous(limits = c(0, 2000), expand = c(0, 0)) +
        labs(
          title = title,
          ### need to use substitute here ###
          subtitle = substitute(
            paste(x, " vs. ", y, " (1997-2018)"),
            list(x = xlab, y = ylab)
          )) +
        xlab(substitute(x, list(x = xlab))) +
        ylab(substitute(y, list(y = ylab))) +
        stat_poly_eq(aes(label = paste(..eq.label.., sep = "~~~")),
          label.x.npc = 0.8, label.y.npc = 0.9,
          eq.with.lhs = "italic(hat(y))~`=`~",
          eq.x.rhs = "~italic(x)",
          formula = formula1, parse = TRUE, size = 5
        ) +
        stat_poly_eq(aes(label = paste(..rr.label.., sep = "~~~")),
          label.x.npc = 0.8, label.y.npc = 0.83,
          formula = formula1, parse = TRUE, size = 5
        ) +
        correlation_theme
    }
    

    Remove / from combo var

    final_df <- final_df %>%
      mutate_at(vars(contains("combo")), funs(str_replace(., "/", "-")))
    
    nested_by_HUC14 <-
      final_df %>%
      group_by(combo) %>%
      nest()
    

    Setup xlab and ylab for plotting

    xlab <- "Specific Conductance" ~ (mu / cm)
    ylab <- "Chloride (mg/L)"
    
    plots <- nested_by_HUC14 %>%
      mutate(
        plot = map2(data, combo, ~ corr_plot_map_way(.x, Specific_conductance, Chloride, .y,
          xlab = xlab,
          ylab = ylab
        )),
        filename = paste0(combo, ".pdf")
      ) %>%
      select(filename, plot)
    
    plots$plot[[1]]
    

    Save to PDF & use cairo_pdf to embed fonts

    map2(plots$filename, plots$plot, ggsave, device = cairo_pdf,
         width = 6, height = 4, units = "in")
    

    Edit: learn more about using math symbols in R here & here