0

Let say I have 2 ggplots

library(ggplot2)
library(cowplot)
set.seed(1)
data = structure(list(fecha = structure(c(1317452400, 1317538800, 1317625200, 
1317711600, 1317798000, 1317884400, 1317970800, 1318057200, 1318143600, 
1318230000, 1318316400, 1318402800, 1318489200, 1318575600, 1318662000, 
1318748400, 1318834800, 1318921200, 1319007600, 1319094000), class = c("POSIXct", 
"POSIXt"), tzone = ""), TempMax = c(26.58, 27.78, 27.9, 27.44, 
30.9, 30.44, 27.57, 25.71, 25.98, 26.84, 33.58, 30.7, 31.3, 27.18, 
26.58, 26.18, 25.19, 24.19, 27.65, 23.92), TempMedia = c(22.88, 
22.87, 22.41, 21.63, 22.43, 22.29, 21.89, 20.52, 19.71, 20.73, 
23.51, 23.13, 22.95, 21.95, 21.91, 20.72, 20.45, 19.42, 19.97, 
19.61), TempMin = c(19.34, 19.14, 18.34, 17.49, 16.75, 16.75, 
16.88, 16.82, 14.82, 16.01, 16.88, 17.55, 16.75, 17.22, 19.01, 
16.95, 17.55, 15.21, 14.22, 16.42)), .Names = c("fecha", "TempMax", 
"TempMedia", "TempMin"), row.names = c(NA, 20L), class = "data.frame")
data['val'] = rnorm(dim(data)[1], 10000, 1)
data

mycolor = c('red', 'green'); names(mycolor) = c('TempMax', 'TempMedia')
p1 <- ggplot(data, aes(x = fecha)) +
        geom_line(aes(y = TempMax, colour = 'TempMax'), size = 1.2) +
        geom_line(aes(y = TempMedia, colour = 'TempMedia'), size = 1.2) +
        scale_colour_manual('color', breaks = names(mycolor), values = mycolor)

p2 = ggplot(data, aes(x = fecha)) +
        geom_bar(aes(y = val), stat = "identity", color = 'grey')

The individual plots for p1 and p2 are perfect, however I want to club them in a single plot window with p2 as secondary axis. I took some reference from ggplot with 2 y axes on each side and different scales, and tried to implement that with below code

ggdraw(insert_yaxis_grob(p1, get_y_axis(p2, position='right')))

But it does not seem to be working. Could you please help to understand the right method, given that data for p2 is not any transformation of the date for p1.

Any pointer will be highly appreciated.

Brian Smith
  • 1,200
  • 4
  • 16

1 Answers1

1

You need to transform the values you wish to plot on the y axis into approximately the same scale as the existing values, then draw a second axis using sec_axis inside the call scale_y_continuous which reverses that transformation. In your case, subtracting 9997 from var and multiplying it by 6 puts it into a reasonable range (between 5 and 30). The secondary axis labels therefore need divided by 6 then added to 9997:

ggplot(data, aes(x = fecha)) +
  geom_col(aes(y = (val - 9997) * 6, fill = 'val')) +
  geom_line(aes(y = TempMax, colour = 'TempMax'), size = 1.2) +
  geom_line(aes(y = TempMedia, colour = 'TempMedia'), size = 1.2) +
  scale_colour_manual('color', breaks = names(mycolor), values = mycolor) +
  scale_fill_manual(values = 'deepskyblue3') +
  scale_y_continuous(name = 'Temp',
                     sec.axis = sec_axis(~(.x / 6 + 9997), name = 'var'))

enter image description here

Allan Cameron
  • 147,086
  • 7
  • 49
  • 87
  • Thanks. Is there any way to control the `range` of the secondary axis and `tick labels` as well? I also want to remove the reference of `val` from legend. Is that possible? – Brian Smith Mar 24 '22 at 16:36
  • You can make the range of the secondary axis anything you like by changing the transformation. You can change the breaks and tick labels to anything you want using the `breaks` and `labels` arguments of `sec_axis`. You can remove the name either by setting `name = ""` or removing it inside `theme` with `axis.title.y.right = element_blank()` – Allan Cameron Mar 24 '22 at 17:21