0

I am trying to plot several panels in ggplot2 while using facet_wrap. I want to have two y-axis. Left side y-axis ranged from 5 to 27 and right side y-axis ranged from 25 to 27. I want to show all the data points with regression line. However, when I am plotting, the variation in the right side y-axis is lower comparing to other dataset so appearing as a flat line. I want to keep right side y-axis from 25 to 27 so that variation in the data can be seem clearly. I used this code 1 but not able to sort it out. Any help is highly appreciated.

library(ggplot2)

scaleFactor <- max(d1$weeks) / max(d1$income)

ggplot(mtcars, aes(x=Year)) +
  geom_smooth(aes(y=weeks), method="loess", col="blue") +
  geom_smooth(aes(y=income * scaleFactor), method="loess", col="red") +
  scale_y_continuous(name="weeks", sec.axis=sec_axis(~./scaleFactor, name="income")) +
  theme(
    axis.title.y.left=element_text(color="blue"),
    axis.text.y.left=element_text(color="blue"),
    axis.title.y.right=element_text(color="red"),
    axis.text.y.right=element_text(color="red")
  )

Blockquote

Gull
  • 107
  • 8
  • Sorry I'm not seeing the problem you mention in the plot your code produces. Particularly, you mention a problem in different panels, but you didn't include a `facet_wrap()` in the code. Can you adapt the code to show the problem more evidently? – teunbrand Feb 04 '21 at 20:35
  • @teunbrand the above code is working fine. However, I want to limit one y-axis from 25-27 and other from 5 to 30. Because maximum value of both variables is similar so the transformation is not helpful. Basically, I want to spread the 25-27 scale as large as 5-30. +facet_warap(~group) is also working fine. – Gull Feb 04 '21 at 20:58
  • I know the code works, it runs without errors. What I'm seeing is this: the blue bit ranges from 4-8 and the red bit from 52-335. How does this relate to the 25-27 and 5-30 ranges you mention? Also, where is this group coming from in the mtcars data? – teunbrand Feb 04 '21 at 21:08
  • @teunbrand very sorry for all the confusion. I used this code to run the analysis on my dataset. I have a very large dataset and now I have added an example of it to show the structure of the data. – Gull Feb 04 '21 at 22:29
  • Does this answer your question? [How to use facets with a dual y-axis ggplot](https://stackoverflow.com/questions/26917689/how-to-use-facets-with-a-dual-y-axis-ggplot) – tjebo Feb 05 '21 at 10:47
  • @tjebo not exactly. The solution given by the teunbrand worked very well. – Gull Feb 05 '21 at 11:12

1 Answers1

3

If this is about making the ranges of the data overlap instead of just rescaling the maximum, you can try the following.

First we'll make function factory to make our job easier:

library(ggplot2)
library(scales)
#> Warning: package 'scales' was built under R version 4.0.3

# Function factory for secondary axis transforms
train_sec <- function(from, to) {
  from <- range(from)
  to   <- range(to)
  # Forward transform for the data
  forward <- function(x) {
    rescale(x, from = from, to = to)
  }
  # Reverse transform for the secondary axis
  reverse <- function(x) {
    rescale(x, from = to, to = from)
  }
  list(fwd = forward, rev = reverse)
}

Then, we can use the function factory to make transformation functions for the data and for the secondary axis.

# Learn the `from` and `to` parameters
sec <- train_sec(mtcars$hp, mtcars$cyl)

Which you can apply like this:

ggplot(mtcars, aes(x=disp)) +
  geom_smooth(aes(y=cyl), method="loess", col="blue") +
  geom_smooth(aes(y= sec$fwd(hp)), method="loess", col="red") +
  scale_y_continuous(name="cyl", sec.axis=sec_axis(~sec$rev(.), name="hp")) +
  theme(
    axis.title.y.left=element_text(color="blue"),
    axis.text.y.left=element_text(color="blue"),
    axis.title.y.right=element_text(color="red"),
    axis.text.y.right=element_text(color="red")
  )
#> `geom_smooth()` using formula 'y ~ x'
#> `geom_smooth()` using formula 'y ~ x'

Here is an example with a different dataset.

sec <- train_sec(economics$psavert, economics$unemploy)

ggplot(economics, aes(date)) +
  geom_line(aes(y = unemploy), colour = "blue") +
  geom_line(aes(y = sec$fwd(psavert)), colour = "red") +
  scale_y_continuous(sec.axis = sec_axis(~sec$rev(.), name = "psavert"))

Created on 2021-02-04 by the reprex package (v1.0.0)

teunbrand
  • 33,645
  • 4
  • 37
  • 63