Ggplot2 with 2 y axis selected with user inputs.

Hello Everyone,

I have a question regarding the effective use of Ggplot2 to create plots with 2 y axis.

I have the following example data frame:

'''

  Date <- c("2021-01-01", "2021-01-05", "2021-01-10", "2021-01-15") 
  Var1 <- c(0.75, 0.5, 0.63, 0.9)
  Var2 <- c(100,200,352, 301)
  Var3 <- c(18,22,17,19)
  Var4 <- c(1000, 987,905,1002)

  DF <- data.frame(Date, Var1, Var2, Var3, Var4)

'''

In the UI I have the following filters:

'''

         selectInput("SelectYVariable1", "Select Y axis Variable", choices = c("Var1", "Var2", Var3", Var4")),
         selectInput("SelectYVariable2", "Select Secondary Y axis Variable", choices = c("Var1", "Var2", Var3", Var4"))                                      

'''

Based on the users' input into the above selectInputs, I would like a Ggplot2 that graphs the two selected variables with the following:

  1. a double y axis scatterplot connected with lines
  2. a primary and secondary y axis title that updates based on the graphed variables
  3. As you can tell based on the sample data, the value range varies quite a bit between the different variables. However, despite the fact that there is no observable relationship between the primary and secondary axis values, this data has value being seen together on a double y axis graph... Therefore, I would like to set individualized y axis ranges for each of the variables. This way if Var1 is selected a completely different y axis range will be displayed in comparison to when Var2 is selected.
  1. a legend that updates based on the variables graphed.

So far I have the following code but am having particular difficulty with goals 2-4

'''

  ggplot(DF, aes(x=Date)) +
    geom_point( aes(y=.data[[input$SelectYVariable1]]), size=2, color="Black") + 
    geom_point( aes(y=.data[[input$SelectYVariable2]]), size=2, color="Red") +
    scale_y_continuous(
      sec.axis = sec_axis(~. +0)) + 
    theme_bw()+
    theme(axis.line = element_line(colour = "Black"),
          axis.title.y = element_text(size=8),
          axis.title.y.right = element_text(size=8),
          axis.title = element_text(face="bold"),
          axis.text.x = element_text(angle = 45, hjust=1)) 

'''

Thank you for any help and knowledge you are willing to share on this topic. I look forward to discussing this with you further.

Here is a start at setting up automatic scaling of the second y axis. I avoided shiny and made the variables V1 and V2 to contain the names of the columns to be plotted. I have not found a way to get a legend to work but I suspect I am not thinking of a well known solution for that.

library(ggplot2)
Date <- c("2021-01-01", "2021-01-05", "2021-01-10", "2021-01-15") 
Var1 <- c(0.75, 0.5, 0.63, 0.9)
Var2 <- c(100,200,352, 301)
Var3 <- c(18,22,17,19)
Var4 <- c(1000, 987,905,1002)

DF <- data.frame(Date, Var1, Var2, Var3, Var4)
V1 <- "Var2"
V2 <- "Var4"
LOG <- log2(max(DF[[V1]])/max(DF[[V2]]))
AwayFromZero <- sign(LOG)*ceiling(abs(LOG))
Scaling <- 2^AwayFromZero

ggplot(DF, aes(x=Date)) +
  geom_point( aes(y=.data[[V1]], color = V1), size=2, color = "black" ) + # 
  geom_point( aes(y=.data[[V2]]*Scaling, color = V2), size=2, color = "red") + 
  scale_y_continuous(
    sec.axis = sec_axis(~. / Scaling  +0, name = V2)) + 
  theme_bw()+
  theme(axis.line = element_line(colour = "Black"),
        axis.title.y = element_text(size=8),
        axis.title.y.right = element_text(size=8),
        axis.text.y.right = element_text(color = "red"),
        axis.title = element_text(face="bold"),
        axis.text.x = element_text(angle = 45, hjust=1)) 

EDIT:
Here is a better version with a legend.

library(ggplot2)
Date <- c("2021-01-01", "2021-01-05", "2021-01-10", "2021-01-15") 
Var1 <- c(0.75, 0.5, 0.63, 0.9)
Var2 <- c(100,200,352, 301)
Var3 <- c(18,22,17,19)
Var4 <- c(1000, 987,905,1002)

DF <- data.frame(Date, Var1, Var2, Var3, Var4)
V1 <- "Var2"
V2 <- "Var4"
LOG <- log2(max(DF[[V1]])/max(DF[[V2]]))
AwayFromZero <- sign(LOG)*ceiling(abs(LOG))
Scaling <- 2^AwayFromZero

ggplot(DF, aes(x=Date)) +
  geom_point( aes(y=.data[[V1]], color = V1), size=2  ) + # 
  geom_point( aes(y=.data[[V2]]*Scaling, , color = V2), size=2 ) + #
  scale_y_continuous(
    sec.axis = sec_axis(~. / Scaling  +0, name = V2)) + 
  scale_color_manual(values = c("black", "red")) +
  labs(color = "Variable") +
  theme_bw()+
  theme(axis.line = element_line(colour = "Black"),
        axis.title.y = element_text(size=8),
        axis.title.y.right = element_text(size=8),
        axis.title = element_text(face="bold"),
        axis.text.x = element_text(angle = 45, hjust=1)) 
1 Like

Thank you for your help! This is much appreciated

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.