0

This is one application from my earlier post on similar subject - Clubbing 2 ggplots in a single windows and putting 2nd one in Secondary axis

Let say I have below ggplot, and I want to have secondary axis for the variable y2

library(ggplot2)
library(quantmod)
dat = data.frame(x = as.yearqtr(seq(as.Date('2002-01-01'), length.out = 17, by = '95 day')),
                    y1 = c(-0.0042, 0.0221, 0.0387, 0.0523, -0.0743, -0.0903, 0.0997, 0.0982, 0.0956, -0.0961, -0.0696, -0.0818, 0.0766, 0.0654, 0.1275, 0.1178, 0.0878),
                    y2 = c(19747, 19343, 19007, 18336, 17534, 16548, 15536, 14400, 13428, 12686, 11877, 11250, 10625, 10122, 9740, 9314, 8892))

ggplot(dat, aes(x = x)) +
  geom_col(aes(y = (y2 - 14000) / 8000), fill = 'red') +
  geom_line(aes(y = y1, colour = 'TempMax'), size = 1.2) +
  scale_y_continuous(name = 'Temp', limits = c(-3, 3),
                     sec.axis = sec_axis(~(.x * 8000 + 14000), name = 'var'))

With this I am getting below plot

enter image description here

This plot looks strange to me. Why my bars for y2 going to negative territory?

I also tried with changing the transformation as,

ggplot(dat, aes(x = x)) +
  geom_col(aes(y = (y2 - 8000) / 8000), fill = 'red') +
  geom_line(aes(y = y1, colour = 'TempMax'), size = 1.2) +
  scale_y_continuous(name = 'Temp', limits = c(-3, 3),
                     sec.axis = sec_axis(~(.x * 8000 + 8000), name = 'var'))

With this, I get below plot

enter image description here

As you see, the range for secondary y axis still going into negative zone. I would ideally expect to see limit of secondary y axis starting from 0. Any idea on how can I make this correction will be very helpful.

Brian Smith
  • 1,200
  • 4
  • 16
  • `sec_axis` is a red-herring, the plot looks identical with that portion removed from your code (except for the second axis, of course, which does nothing to the main plot elements/layers). – r2evans Mar 24 '22 at 22:07
  • Your bars go negative because `range(dat$y2 - 14000) / 8000` returns `-0.638500 0.718375`. Is your hard-coded `14000` (and possibly `8000`) supposed to be something else? – r2evans Mar 24 '22 at 22:09
  • I wanted to approximately match the transformed range of `y2` to that of `y1`. But why that should matter? I am again transforming back with `~(.x * 8000 + 14000)`. Should not it negate my earlier transformation? What is the correct rule? I basically want to automate this transformation so that `y1` and `y2` can co-exist with `y2` in secondary axis – Brian Smith Mar 24 '22 at 22:12
  • Have a look at your y2. Starting from the 9th element, your red bars become negative (when compared to the left y axis). Your 9th element from y2 is 13428. In your geom_col you re-calculate the value `y2 - 14000) / 8000`, which for 13428 is equal to -0,0715, a negative value (on the left y axis). You then recalculate your second y axis as .x * 8000 + 14000, which for 0 (on the first y axis) equals to 0 * 8000 + 14000 = 14000 on your second y axis. The calculation you did was right, and the 9th value from y2 (13428) is indeed 13428 when read according to your second y axis. – Gnueghoidune Mar 24 '22 at 22:35
  • @Gnueghoidune I changed the transformation to `(y2 - 8000) / 8000)`. With this, I get the range of `right y axis` starting from negative value, while the plot appears to be okay. Is there any way to force the starting value of `secondary y axis` from 0? I modified my original post with this information – Brian Smith Mar 25 '22 at 03:27
  • remove the addition/subtraction and stick to division/multiplication only. – Gnueghoidune Mar 25 '22 at 05:29
  • If I do `geom_col(aes(y = (y2 - 0) / 8000), fill = 'red')` and `sec.axis = sec_axis(~(.x * 8000 + 0)` I still get the range of `secondary y axis` in negative territory – Brian Smith Mar 25 '22 at 08:32

2 Answers2

0

In order to adjust/manipulate/force the sec.axis to start at 0 you can use expand = c(-3, 3)

Sample code:

   library(ggplot2)
library(quantmod)

ggplot(dat, aes(x = x)) +
  geom_col(aes(y = (y2 - 14000) / 8000), fill = 'red') +
  geom_line(aes(y = y1, colour = 'TempMax'), size = 1.2) +
  scale_y_continuous(name = 'Temp', 
                     sec.axis = sec_axis(~(.x * 8000 + 14000), name = 'var'), expand = c(-3, 3))

Plot:

enter image description here

With regards to your remark - standalone basis of the sec.axis

with expand =c (-3,3)

enter image description here

and with limits=c(-3,3)

enter image description here

For the second code, I would use expand=c(0,1)

enter image description here

You could scale the x axis as well

Sample code:

ggplot(dat, aes(x = x)) +
  geom_col(aes(y = (y2 - 8000) / 8000), fill = 'red') +
  geom_line(aes(y = y1, colour = 'TempMax'), size = 1.2) +
  scale_y_continuous(name = 'Temp', expand = c(0, 0),
                     sec.axis = sec_axis(~(.x * 8000 + 8000), name = 'var'))+
  scale_x_continuous(expand=c(0,0))+
  theme_bw()

Plot:

enter image description here Sample data:

dat = data.frame(x = as.yearqtr(seq(as.Date('2002-01-01'), length.out = 17, by = '95 day')),
                 y1 = c(-0.0042, 0.0221, 0.0387, 0.0523, -0.0743, -0.0903, 0.0997, 0.0982, 0.0956, -0.0961, -0.0696, -0.0818, 0.0766, 0.0654, 0.1275, 0.1178, 0.0878),
                 y2 = c(19747, 19343, 19007, 18336, 17534, 16548, 15536, 14400, 13428, 12686, 11877, 11250, 10625, 10122, 9740, 9314, 8892))
Rfanatic
  • 2,224
  • 1
  • 5
  • 21
  • Thanks. I dont think if I plot `y2` standalone basis, I would get similar plot like yours – Brian Smith Mar 25 '22 at 08:41
  • Thanks for edits. But if you please look at the 2nd plot in my original post, you can see that the plot for `y2` is different (sort of descending), but in your plot it is different. – Brian Smith Mar 25 '22 at 08:51
  • @Brian Smith sorry I just observed it! – Rfanatic Mar 25 '22 at 08:52
  • Nps. I just want that in my 2nd plot, the `secondary y axis` should start from 0. I am clueless why this axis is taking negative values where no values for `y2` is negative – Brian Smith Mar 25 '22 at 08:56
  • Your current plot is almost perfect, except that the bar plots looks kike floating in vaccum (like mine), is it possible to anchor them at 0 in `secondary y axis`? – Brian Smith Mar 25 '22 at 08:58
0

Would this suit your needs?

ggplot(dat, aes(x = x)) +
  geom_col(aes(y = (y2 / 8000), fill = 'red') +
  geom_line(aes(y = y1, colour = 'TempMax'), size = 1.2) +
  scale_y_continuous(name = 'Temp', limits = c(-0.2, 3),
                     sec.axis = sec_axis(~(.x * 8000), name = 'var'))

enter image description here

Gnueghoidune
  • 1,237
  • 4
  • 13