rggplot2scalefacet-wrap

R scale_y_facet with violin plot: negative log values


Assume a dataframe

n <- 100
d <- data.frame("name" = c(rep("A", n), rep("B", n)),
                "type" = rep(c("X", "Y"), 2*n), 
                "value" = c(rnorm(n, 0, 1), rbeta(n, 1, 3)))

And the following violin plot:

ggplot(d, aes(name, value, fill = type)) + 
  geom_violin(trim = F, position = dodge, na.rm = T) + 
  geom_boxplot(width = 0.1, position = dodge, na.rm = T) +
  facet_wrap(facets = ~name, scales = 'free') +
  theme(legend.position = "bottom",
        axis.title.x = element_blank(), 
        legend.title = element_blank(),
        axis.text.x = element_blank(),
        axis.ticks.x = element_blank(),
        legend.key.width = unit(0.5, "cm"))   +
  ggh4x::scale_y_facet(
    name == "B",
    trans  = "log10",
    breaks = breaks_log(),
    labels = label_log()) 

which unfortunately doesn't work, as I get the message

Warning messages:
1: In transformation$transform(x) : NaNs produced
2: In scale_facet(expr = enquo(expr), "y", ..., type = type) :
  log-10 transformation introduced infinite values.
3: In transformation$transform(x) : NaNs produced
4: In scale_facet(expr = enquo(expr), "y", ..., type = type) :
  log-10 transformation introduced infinite values.
5: In transformation$transform(x) : NaNs produced
6: In scale_facet(expr = enquo(expr), "y", ..., type = type) :
  log-10 transformation introduced infinite values.
7: In transformation$transform(x) : NaNs produced
8: In scale_facet(expr = enquo(expr), "y", ..., type = type) :
  log-10 transformation introduced infinite values.

The values fed into the log transform are strictly positive, so that's not a problem. I suppose the problem lies in the fact that only after the log transformation do I obtain negative values (the indicator for that is the limit for the y-axis starts above 0). So, I need to adjust the y-axis, or more precisely, allow breaks to take negative values. How to do that?


Solution

  • The violin plot extends the data at the tails (since you did not trim), thus you may get some negative values. You can prevent the warnings by using a pseudo_log transform:

    ggplot(d, aes(name, value, fill = type)) + 
      geom_violin(trim = F, position = "dodge", na.rm = T) + 
      geom_boxplot(width = 0.1, position = "dodge", na.rm = T) +
      facet_wrap(facets = ~name, scales = 'free') +
      theme(legend.position = "bottom",
            axis.title.x = element_blank(), 
            legend.title = element_blank(),
            axis.text.x = element_blank(),
            axis.ticks.x = element_blank(),
            legend.key.width = unit(0.5, "cm"))   +
      ggh4x::scale_y_facet(
        name == "B",
        #trans  = "log10",
        #breaks = breaks_log(),
        trans  = pseudo_log_trans(base = 10),
        breaks = 10^(c(-5, -1, 0)),
        labels = label_log()) 
    

    enter image description here

    Note that if you omit the call to violin_plot (or trim the tails), you won't get the warnings.