Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
470 views
in Technique[技术] by (71.8m points)

r - Dual y-axis while using facet_wrap in ggplot with varying y-axis scale

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

question from:https://stackoverflow.com/questions/66053185/dual-y-axis-while-using-facet-wrap-in-ggplot-with-varying-y-axis-scale

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...