ggplot second y-axis: how to specify a secondary axis if I don't want to scale my second y variable
1
0
Entering edit mode
5.0 years ago
endretoth ▴ 40

Hi All,

I'm a beginner with ggplot and I have a simple but specific problem. Unfortunately, I cannot find a simple solution on any website. May I kindly ask for your help?

I would like to create a ggplot line plot with two y axis, with one y on the left side and one y on the right side. However, all options I find on the internet is with scaling the variable. I would like to use my variable just as it is, without scaling, also one of the variables has some missing values. Thus, for me, it seems quite complicated to create the graph. For example, this is the data: (the values are from the Evanno method following a Structure analysis, if it is helpful for someone)

k(x_axis) elpdmean(first_y_axis,_left_side) elpdmin(error_for_first_y_axis) elpdmax(error_for_first_y_axis) deltaK(second_y_axis,_right_side)
1 -7993.02 -7993.2 -7992.8 NA
2 -8929.45 -10160.1 -8478.3 5.02022896057085
3 -7464.6 -7603.1 -7387.5 27.4350590318052
4 -7769.82 -9053.1 -7403.8 1.29238220974692
5 -7379.98 -7560.3 -7304.1 4.92354930446963
6 -7450.48 -8753.1 -7262.5 0.123848798857256
7 -7463.89 -8221.6 -7245 NA

Here is the R script:

k<-c(1,2,3,4,5,6,7)
lkmean<-c(-7993.02,-8929.45,-7464.6,-7769.82,-7379.98,-7450.48,-7463.89)
lkmin<-c(-7993.2,-10160.1,-7603.1,-9053.1,-7560.3,-8753.1,-8221.6)
lkmax<-c(-7992.8,-8478.3,-7387.5,-7403.8,-7304.1,-7262.5,-7245.0)
deltak<-c(NA,5.02022896057085,27.4350590318052,1.29238220974692,4.92354930446963,0.123848798857256,NA)

test.data<-data.frame(k,lkmean,lkmin,lkmax,deltak)

library(ggplot2)

p<-ggplot(test.data, aes(k, lkmean)) +
  geom_line()

I appreciate all the suggestions and helps :) Thank you!

R ggplot structure • 24k views
ADD COMMENT
1
Entering edit mode
5.0 years ago
Ido Tamir 5.2k

https://ggplot2.tidyverse.org/reference/sec_axis.html

everything more requires you to post some easily reproducible code

ADD COMMENT
0
Entering edit mode

Hi Ido,

This is exactly what I mentioned, this is a solution when you need to scale your data. If you look at the example this requires to use the scale_y_continous argument:

p + scale_y_continuous(sec.axis = sec_axis(~ . + 10))

I would like to create the plot without scaling. Therefore this is not really good for me :(

ADD REPLY
1
Entering edit mode

the function scale_y_continuous can be used without any scaling, like the ones in the example Ido has mentioned. If you look in the help of this function, you would know that the scaling happens when you specify the trans option

ADD REPLY
0
Entering edit mode

Hi Hasani,

I'm suffering with this R script. I don't clearly understand what is this ~.*10 means. My I ask for some help?

p <- ggplot(test.data, aes(x = k))+
  geom_line(aes(y = lkmean, colour="#606060"))+
  geom_line(aes(y = deltak, colour="#303030"))+
  scale_y_continuous(sec.axis = sec_axis(~.*10, name = "TEST"))
p

How can I tell to ggplot which variable will be on the second y axis?

ADD REPLY
1
Entering edit mode

The ~. means: use the values as defined in the aes, in your example it is lkmean. what comes after ~. is a simple arithemtic operation. I'm not sure what exactly are you trying to reach by having two axises, but in principle, what you are doing is combining two plots merly because they share the same x-axis. I would recommend to use grid or facet, or have a look at the this thread ggplot with 2 y axes on each side and different scales As Ido said, the second axis is meant to be a sort of linear relation with first one, which what the work around provided by answers 3,4 & 5 actually is. That being said, carefully read answer 2 (by hadley).

hth

ADD REPLY
1
Entering edit mode

Dear Hasani & Ido,

I could create the plot based on the forum that Hasani suggested. However, I cannot add error bars (lkmin and max). I have tried several ways. Please help me this is the last step.

This is my script:

ylim.deltak <- c(0, 30)    # deltak
ylim.lkmean <- c(-10000, -6000)   # lkmean

b <- diff(ylim.deltak)/diff(ylim.lkmean)
a <- b*(ylim.deltak[1] - ylim.lkmean[1])

ggplot(test.data, aes(k, deltak)) +
  geom_line(size = 2, color = "red") +
  geom_line(aes(y = a + lkmean*b), size = 2, color = "blue") +
  scale_y_continuous("ΔK", sec.axis = sec_axis(~ (. - a)/b, name = "Mean L(K) ± SD")) +
  scale_x_continuous("K", breaks = 1:7) +
  ggtitle("combined plot")

Plot below

ADD REPLY
1
Entering edit mode

maybe you want something which ggplot makes difficult on purpose. The 2. axis has to be a (linear?) transformation of the 1. axis in ggplot2. this is by design, because everything else is confusing for the reader.

ADD REPLY

Login before adding your answer.

Traffic: 2516 users visited in the last hour
Help About
FAQ
Access RSS
API
Stats

Use of this site constitutes acceptance of our User Agreement and Privacy Policy.

Powered by the version 2.3.6