Dual Y axis plot with different scales, using data from a dataframe

Hi folks, does anybody know how to create a functioning dual Y axis plot with different scales, using data from a data frame? I've tried different packages but either can't wrap my head around them or they do not work for me.

Please post a small data set that can be used to make the kind of plot you want. If you have an existing data frame, post the output of using the dput() function on that data frame. If it is called DF, post the output of

dput(DF)

You could also post an example of the data.frame() function making the desired data frame.

How are the scales on the two y axes related? Is one, say, 10x the other or is the relationship more complex?

Is this what you need?

Hi there, so my data would look something like this:

x y1 y2
0 0.01 845
1 0.04 845
2 0.02 844
3 0.08 845
4 0.04 846
5 0.06 844

I tried to use this, but the trans funtion doesn't help due to the scale differences.

Here is an example using your data.

library(ggplot2)
DF <- tibble::tribble(
  ~x,   ~y1,    ~y2,
  0,    0.01,   845,
  1,    0.04,   845,
  2,    0.02,   844,
  3,    0.08,   845,
  4,    0.04,   846,
  5,    0.06,   844
)
ggplot(DF, aes(x)) +
  geom_line(aes(y = y1)) +
  geom_line(aes(y = (y2/250 - 3.3)), color = "red") +
  scale_y_continuous(sec.axis = sec_axis(trans = ~(. + 3.3) * 250, name = "y2")) +
  theme(axis.text.y.right = element_text(color = "red"))

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

2 Likes

I have posted similar topic two years ago:

https://forum.posit.co/t/how-to-add-secondary-y-axis-to-ggplot-with-proper-values-scale/121345

Maybe someone could provide help/solution by any chance, as it remains unsolved.

1 Like

Thank you for this, ill try it when I get back from work tonight and I'll update

Apologies for taking so long to get back to you, so it does work, but I'm not sure how to limit the scales to essentially the exact values of the data.

To tune the y axis values, you would have to adjust the transformation used to generate the values of the second y axis. I my example, I divided y = y2/250 - 3.3 in geom_line() and the inverse of that in sec_axis().
A much less fiddly approach would be to plot the data sets in two facets in a single column. It is still easy to compare the behavior of the two variables but ggplot handles the scaling automatically.

library(ggplot2)
library(tidyr)
DF <- tibble::tribble(
  ~x,   ~y1,    ~y2,
  0,    0.01,   845,
  1,    0.04,   845,
  2,    0.02,   844,
  3,    0.08,   845,
  4,    0.04,   846,
  5,    0.06,   844
)
DFLng <- DF |> pivot_longer(cols = y1:y2, names_to = "Var")
DFLng
#> # A tibble: 12 × 3
#>        x Var    value
#>    <dbl> <chr>  <dbl>
#>  1     0 y1      0.01
#>  2     0 y2    845   
#>  3     1 y1      0.04
#>  4     1 y2    845   
#>  5     2 y1      0.02
#>  6     2 y2    844   
#>  7     3 y1      0.08
#>  8     3 y2    845   
#>  9     4 y1      0.04
#> 10     4 y2    846   
#> 11     5 y1      0.06
#> 12     5 y2    844
ggplot(DFLng, aes(x, value)) +
  geom_line() +
  facet_wrap(~Var, scales = "free", ncol = 1)

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

Thanks, I'll give it a go!

This topic was automatically closed 42 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.