Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Using facet_wrap in ggplot2, how can log and linear y-axis scales be mixed (with appropriate axis text)?

I’d like to make a facet_wrap plot with both linear- and and log-scale y-axes (on different facets), but obviously that isn’t easily done.

Here’s an example of the kind of dataset I’m working with:

library(tidyverse)

df <- tibble(TIME = rep(1:10, 2),
             PARAM = rep(c("A", "B"), each = 10),
             VAL = c(seq.int(1, 50, length.out = 10),
                     c(1000, 100, 1, 5, 1, 10, 5, 10, 100, 1000)),
             Y_INT = rep(c(NA, 10), each = 10))

And plotted on a linear scale:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

ggplot(data = df, aes(x = TIME, y = VAL)) +
  geom_line() +
  geom_hline(aes(yintercept = Y_INT), linetype = 2, color = "gray50") +
  facet_wrap(~PARAM, ncol = 1, scales = "free_y")

Example 1: A faceted plot with linear scales

One solution is to manually put data on a log scale (here, PARAM B data):

df_log <- df |>
  mutate(VAL = ifelse(PARAM == "B", log10(VAL), VAL)) |>
  mutate(Y_INT = ifelse(PARAM == "B", log10(Y_INT), Y_INT))

ggplot(data = df_log, aes(x = TIME, y = VAL)) +
  geom_line() +
  geom_hline(aes(yintercept = Y_INT), linetype = 2, color = "gray50") +
  facet_wrap(~PARAM, ncol = 1, scales = "free_y")

Example 2: A plot with the correct scale on the log-scale facet, but with axis text that isn't readily understood

However, what I would like is something like this:

Example 3: A plot with linear and log y-axes, but made using a ggarrange function

I needed to use ggpubr::ggarrange to generate that image, and I’m trying to stick with facet_wrap.

So, the final question: how can linear and log y-axis scales be used in a single facet_wrap plot with appropriate axis text, as above?

>Solution :

You can use ggh4x::scale_y_facet() to have greater control over this. Disclaimer: I’m the author of ggh4x. There’s no means to do a secondary axis title though.

library(ggplot2)
library(scales)

df <- data.frame(TIME = rep(1:10, 2),
                 PARAM = rep(c("A", "B"), each = 10),
                 VAL = c(seq.int(1, 50, length.out = 10),
                         c(1000, 100, 1, 5, 1, 10, 5, 10, 100, 1000)),
                 Y_INT = rep(c(NA, 10), each = 10))

ggplot(data = df, aes(x = TIME, y = VAL)) +
  geom_line() +
  geom_hline(aes(yintercept = Y_INT), linetype = 2, color = "gray50") +
  facet_wrap(~PARAM, ncol = 1, scales = "free_y") +
  ggh4x::scale_y_facet(
    PARAM == "B",
    trans  = "log10",
    breaks = breaks_log(),
    labels = label_log()
  )
#> Warning: Removed 10 rows containing missing values or values outside the scale range
#> (`geom_hline()`).

Created on 2023-07-31 with reprex v2.0.2

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading