1

I have a dataframe with 4 variables one of them is time, 2 are speed and the last one is Precipitation. The scales between the speed and precipitation are completely different. I want to plot two Y axis, one for speed and a completely different Y axis for Precipitation. Also, Is it possible to help me re ordering the legends manually?

data <- structure(list(Time = structure(c(147L, 25L, 44L, 20L, 7L, 74L, 
51L, 156L, 62L, 115L), .Label = c("06:00:00", "06:05:00", "06:10:00", 
"06:15:00", "06:20:00", "06:25:00", "06:30:00", "06:35:00", "06:40:00", 
"06:45:00", "06:50:00", "06:55:00", "07:00:00", "07:05:00", "07:10:00", 
"07:15:00", "07:20:00", "07:25:00", "07:30:00", "07:35:00", "07:40:00", 
"07:45:00", "07:50:00", "07:55:00", "08:00:00", "08:05:00", "08:10:00", 
"08:15:00", "08:20:00", "08:25:00", "08:30:00", "08:35:00", "08:40:00", 
"08:45:00", "08:50:00", "08:55:00", "09:00:00", "09:05:00", "09:10:00", 
"09:15:00", "09:20:00", "09:25:00", "09:30:00", "09:35:00", "09:40:00", 
"09:45:00", "09:50:00", "09:55:00", "10:00:00", "10:05:00", "10:10:00", 
"10:15:00", "10:20:00", "10:25:00", "10:30:00", "10:35:00", "10:40:00", 
"10:45:00", "10:50:00", "10:55:00", "11:00:00", "11:05:00", "11:10:00", 
"11:15:00", "11:20:00", "11:25:00", "11:30:00", "11:35:00", "11:40:00", 
"11:45:00", "11:50:00", "11:55:00", "12:00:00", "12:05:00", "12:10:00", 
"12:15:00", "12:20:00", "12:25:00", "12:30:00", "12:35:00", "12:40:00", 
"12:45:00", "12:50:00", "12:55:00", "13:00:00", "13:05:00", "13:10:00", 
"13:15:00", "13:20:00", "13:25:00", "13:30:00", "13:35:00", "13:40:00", 
"13:45:00", "13:50:00", "13:55:00", "14:00:00", "14:05:00", "14:10:00", 
"14:15:00", "14:20:00", "14:25:00", "14:30:00", "14:35:00", "14:40:00", 
"14:45:00", "14:50:00", "14:55:00", "15:00:00", "15:05:00", "15:10:00", 
"15:15:00", "15:20:00", "15:25:00", "15:30:00", "15:35:00", "15:40:00", 
"15:45:00", "15:50:00", "15:55:00", "16:00:00", "16:05:00", "16:10:00", 
"16:15:00", "16:20:00", "16:25:00", "16:30:00", "16:35:00", "16:40:00", 
"16:45:00", "16:50:00", "16:55:00", "17:00:00", "17:05:00", "17:10:00", 
"17:15:00", "17:20:00", "17:25:00", "17:30:00", "17:35:00", "17:40:00", 
"17:45:00", "17:50:00", "17:55:00", "18:00:00", "18:05:00", "18:10:00", 
"18:15:00", "18:20:00", "18:25:00", "18:30:00", "18:35:00", "18:40:00", 
"18:45:00", "18:50:00", "18:55:00", "19:00:00"), class = "factor"), 
    variable = structure(c(3L, 1L, 3L, 2L, 1L, 1L, 1L, 3L, 1L, 
    2L), .Label = c("Ground Speed(km/h)", "Precipitation(cm/h)", 
    "Predicted Speed(km/h)"), class = "factor"), value = c(105.507629394531, 
    101.367, 105.266487121582, 3.0613, 99.758, 106.194, 101.367, 
    106.969375610352, 107.803, 0)), row.names = c(NA, -10L), class = "data.frame")

I tried this code below:

data %>%
  gather(variable, speed, -Time) %>%
  ggplot(aes(x = Time, y = speed, group = variable,colour = variable, linetype=variable)) + 
  geom_line()+
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) + 
  scale_linetype_manual(values=c("dashed", "dotted", "solid"))+
  scale_x_discrete(breaks=c("07:00:00","10:00:00","13:00:00", "15:00:00", "18:00:00"),
                   labels=c("7:00", "10:00", "13:00", "15:00", "18:00"))+
  xlab("Time")+
  ylab("Speed(km/h)")+
  theme(text=element_text(size=10,  family="Cambria"))+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        panel.border = element_rect(colour = "black", fill=NA, size=1),
        panel.background = element_blank())+
  theme(legend.position = "bottom")+scale_size(range=c(1,9), guide="none")+
  theme(legend.key.size = unit(0.45, "cm"))+
  scale_y_continuous("Precipitation(cm/h)", sec.axis = sec_axis(~., name = "Precipitation"))
dww
  • 30,425
  • 5
  • 68
  • 111
mustafa
  • 203
  • 1
  • 8
  • 1
    I think this is not possible in ggplot (unless the two scales are transformations of each other). See here: https://stackoverflow.com/questions/3099219/ – AndreasM Aug 11 '20 at 18:04
  • @AndreasM Thanks! I have already checked that and it doesn't work in my case. – mustafa Aug 11 '20 at 18:09

2 Answers2

2

In response to the comments provided, perhaps you can consider using facet_wrap with scales="free".

data %>%
  ggplot(aes(x = Time, y = value, colour = variable)) + 
  geom_line(group = 1)+
  facet_wrap(~variable, scales = "free")+
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))

Created on 2020-08-11 by the reprex package (v0.3.0)

Eric
  • 2,699
  • 5
  • 17
  • I have so many dataframes of the same three variables and the precipitation varies widely so I need and automatic code that solves the problem. – mustafa Aug 11 '20 at 18:10
1

Well you do have to transform but you can get pretty close with this. I picked * 30 as the transform but that was just a guess. I also added how to reorder legend by reordering the factors coming into ggplot and got rid of some unnecessaries.

library(dplyr)
library(ggplot2)

data$variable <- 
  forcats::fct_relevel(data$variable, 
    "Ground Speed(km/h)", 
    "Predicted Speed(km/h)", 
    "Precipitation(cm/h)" )

data <- 
  data %>% 
  mutate(newvalue = case_when(
    variable == "Precipitation(cm/h)" ~ value * 30,
    TRUE ~ value)
    )

ggplot(data, aes(x = Time, y = newvalue, group = variable, color = variable, linetype = variable)) +
  geom_line() + 
  scale_y_continuous(sec.axis = sec_axis(~. / 30, name = "Precipation cm/hr")) +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) + 
  xlab("Time") +
  ylab("Speed(km/h)") +
  theme(text=element_text(size=10))+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        panel.border = element_rect(colour = "black", fill=NA, size=1),
        panel.background = element_blank()) +
  theme(legend.position = "bottom") + 
  theme(legend.key.size = unit(0.45, "cm")) 

Chuck P
  • 3,862
  • 3
  • 9
  • 20