0

This is driving me crazy, mostly because I've done it before and can't find the code for it.

Let's say I have the following dataframe:

df <- tibble(
  TIME = 0:19,
  VAL1 = seq(from = 10, to = 2500, length.out = 20),
  VAL2 = seq(from = 1, to = 30, length.out = 20))

I'd like VAL1, which has a large range, to be plotted on the left y-axis using a log scale, and VAL2, which has a much smaller range, to be plotted on the right y-axis using a linear scale.

I know there are other examples out there (see here and here), but I can't seem to get the y-axes to line up correctly using those approaches.

Any thoughts?

jsgraydon
  • 222
  • 1
  • 7

1 Answers1

1

ggplot2's secondary axes have to be a linear transformation of the primary axis. So we can convert VAL1 to its log so that both series can be mapped to a linear scale. (With some labeling to make the primary axis levels show exponentials.)

Here, I divide VAL2 by 12 and add one to make it cover similar range as the log10 of VAL1. The secondary axis labeling needs to the reverse, subtracting 1 and then multiplying by 12.

ggplot(df, aes(TIME)) +
  geom_line(aes(y = log10(VAL1), color = "VAL1")) +
  geom_line(aes(y = VAL2/12 + 1, color = "VAL2")) +
  scale_y_continuous(
    labels = function(x) scales::comma(round(10^x), accuracy = 1),
    breaks = c(0:10, 0:10 + 0.3979, 0:10 + 0.69897),
    minor_breaks = NULL,
    sec.axis = sec_axis(~(.-1)*12))

enter image description here

Jon Spring
  • 55,165
  • 4
  • 35
  • 53
  • Awesome, thanks. If I want to create a facet_grid of these plots, can you think of a way to have the scaling factor change with each parameter I facet by? So for my actual data, 12 was appropriate, but then I have parameters that need 20 and 40. – jsgraydon May 11 '23 at 13:38
  • 1
    You can use free scales for each facet, but combining log and linear scales in different facets sounds very tricky. Easier to use `patchwork` to align two separate plots. Or you might look into my favorite transformation, `scales::pseudo_log_trans()`, which combines a linear scale near zero with a log scale farther out, with the transition point up to you ("sigma"). That might work for some sets of data which operate over various orders of magnitude. – Jon Spring May 11 '23 at 14:44