0

I am trying to plot the data using two y axis.

p <- ggplot(mydf, aes(x = pos)) +
  geom_line(aes(y = data1, colour="data1")) +
  geom_line(aes(y = data2, colour="data2")) +
  scale_y_continuous(limits = c(0.40, 0.90), breaks=c(0.40, 0.050, 0.60, 0.70, 0.80, 0.90), sec.axis = sec_axis(~., name = "data1")) +
  labs(y = "freq",
       x = "position",
       colour = "") +
  scale_colour_hue(labels = c("data1",
                              "data2"),
                   l = 40) +
  ggtitle("title of the plot") +
  theme_bw() +
  theme(text=element_text(size=8)) +
  theme(plot.title = element_text(hjust = 0.5, size =8)) +
  theme(legend.direction = "horizontal", legend.position = "bottom", legend.box = "vertical")
plot(p)

The first y axis values range from 0.40-0.90, che second y axis values range rom 0.50-0.60. How to adjust the plot?

pos  data1  data2
1  0.9  0.6
2  0.8  0.6
3  0.8  0.6
4  0.7  0.6
5  0.6  0.5
6  0.5  0.5
7  0.4  0.5

mydf <- structure(list(win_mid = 88:97, emboss = c(0.8189, 0.81395, 0.818533333333333, 
0.820825, 0.81846, 0.816883333333333, 0.815757142857143, 0.8149125, 
0.814255555555556, 0.81373), clc = c(0.5985568621, 0.5985568621, 
0.598507734833333, 0.59852001665, 0.59852738574, 0.5986134848, 
0.598590549371429, 0.598623096925, 0.598573214244444, 0.59846694016
)), row.names = 76:85, class = "data.frame")
user3224522
  • 1,119
  • 8
  • 19
  • 1
    1) Could you attach a sample of your data using dput(). 2) Does this help https://stackoverflow.com/questions/3099219/ggplot-with-2-y-axes-on-each-side-and-different-scales? 3) Some believe that double y-scales are bad practise, and ggplot requires some tweaks for accomplishing that (see linked question) – Otto Kässi Mar 29 '21 at 07:26

1 Answers1

1

Plotting secondary y-axis on ggplot2 is more of a mathematical problem than a plotting one. In general we need to take one set of values and fit them between a min and max value. This answer has the general formula https://stackoverflow.com/a/5295202/3962914 which can be implemented in this case as -

library(ggplot2)

ggplot(mydf, aes(x = pos)) +
  geom_line(aes(y = data1, colour="data1")) +
  geom_line(aes(y = data2, colour="data2")) +
  scale_y_continuous(limits = c(0.40, 0.90), 
                     breaks=c(0.40, 0.050, 0.60, 0.70, 0.80, 0.90), 
                     sec.axis = sec_axis(~{
                       a <- min(mydf$data2)
                       b <- max(mydf$data2)
                       (((b-a) * (. - min(.)))/diff(range(.))) + a
                     }, name = "data1")) +
  labs(y = "freq",
       x = "position",
       colour = "") +
  scale_colour_hue(labels = c("data1","data2"),
                   l = 40) +
  ggtitle("title of the plot") +
  theme_bw() +
  theme(text=element_text(size=8)) +
  theme(plot.title = element_text(hjust = 0.5, size =8)) +
  theme(legend.direction = "horizontal", 
        legend.position = "bottom", 
        legend.box = "vertical")

enter image description here


On the dput data :

ggplot(mydf, aes(x = win_mid)) +
  geom_line(aes(y = emboss, colour="emboss")) +
  geom_line(aes(y = clc, colour="clc")) +
  scale_y_continuous(limits = c(0.40, 0.90), 
                     breaks=c(0.40, 0.050, 0.60, 0.70, 0.80, 0.90), 
                     sec.axis = sec_axis(~{
                       a <- min(mydf$clc)
                       b <- max(mydf$clc)
                       (((b-a) * (. - min(.)))/diff(range(.))) + a
                     }, name = "emboss")) +
  labs(y = "freq",
       x = "position",
       colour = "") +
  scale_colour_hue(labels = c("emboss","clc"),
                   l = 40) +
  ggtitle("title of the plot") +
  theme_bw() +
  theme(text=element_text(size=8)) +
  theme(plot.title = element_text(hjust = 0.5, size =8)) +
  theme(legend.direction = "horizontal", 
        legend.position = "bottom", 
        legend.box = "vertical")

enter image description here

data

mydf <- structure(list(pos = 1:7, data1 = c(0.9, 0.8, 0.8, 0.7, 0.6, 
0.5, 0.4), data2 = c(0.6, 0.6, 0.6, 0.6, 0.5, 0.5, 0.5)), 
class = "data.frame", row.names = c(NA, -7L))
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
  • thanks a lot.. I do not why, but I get exactly the same graph as mine, with second y without any changes.. – user3224522 Mar 29 '21 at 08:39
  • That's strange. I just restarted R and checked, I still get the same plot as shown in my answer. Can you try the code on the data in my answer? – Ronak Shah Mar 29 '21 at 08:42
  • it works on your data, but on my data it does not change the second y axis at all... – user3224522 Mar 29 '21 at 08:55
  • 1
    Please add your data in a similar reproducible format using `dput` which we can copy and use. Edit your post to include `dput(head(mydf, 10))`. – Ronak Shah Mar 29 '21 at 08:58
  • It works fine for me. Just had to change the variable names. – Ronak Shah Mar 29 '21 at 09:06
  • 1. i dont have values on the second y axis, it is empty 2. I get exactly the same graph, but when I plot my whole data, the range of the second y axis is in not in 0.5-06.... – user3224522 Mar 29 '21 at 09:08
  • You don't have values on y-axis if you use the `dput` data from your post? – Ronak Shah Mar 29 '21 at 09:09
  • BTW I have not assigned the plot output to `p`. My code will just display the output in the viewer. If you are checking `p` you need to assign it to that value. `p <- ggplot(mydf, aes(x = win_mid)) + ...rest of the code` and then check `p`. – Ronak Shah Mar 29 '21 at 09:12
  • yes, this is clear enough, the issue with the p i mean – user3224522 Mar 29 '21 at 09:13
  • I restarted, but I do not get the second y values as you do. I get this warning for the whole dataset: Warning messages: 1: In min(x) : no non-missing arguments to min; returning Inf 2: In max(x) : no non-missing arguments to max; returning -Inf 3: In min(x) : no non-missing arguments to min; returning Inf 4: In max(x) : no non-missing arguments to max; returning -Inf 5: In min(x) : no non-missing arguments to min; returning Inf 6: In max(x) : no non-missing arguments to max; returning -Inf – user3224522 Mar 29 '21 at 09:17
  • 1
    You might need to add `na.rm = TRUE` in `min`, `max` and `range` function everywhere. – Ronak Shah Mar 29 '21 at 09:22
  • I eliminated all NA's, and now I get the y axes ticks, although the plot remains always small based on the values of the 1sr y axes... ((( – user3224522 Mar 29 '21 at 09:26
  • NOTE, in the first graph, the second line is not aligned on the second y axes, but on the first. Since it should be from 0.6 to 0.5... – user3224522 Mar 29 '21 at 09:35
  • I solved it following this thread: https://stackoverflow.com/questions/3099219/ggplot-with-2-y-axes-on-each-side-and-different-scales – user3224522 Mar 29 '21 at 09:47