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")
)
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)