Home > Blockchain >  R Bar Plot With Double Y Axis Formatting
R Bar Plot With Double Y Axis Formatting

Time:09-29

I have the below code and want to understand how I can:

  • increase the y axis limits to 'val' = 170000 (instead of 150000), '%' = 100% (instead of 75%)

  • order the months correctly

    Total_Wth <- c(88959, 100396, 117989, 130561, 150282, 148970)
    App_1 <- c(0.91, 0.9, 0.91, 0.88, 0.9, 0.9)
    App_2 <- c(0.09, 0.1, 0.09, 0.12, 0.10, 0.10)
    
    df <- data.frame(x, Total_Wth, App_1, App_2)
    transf_fact <- max(df$Total_Wth)/max(df$App_1)
    head(df)
    
    df %>%
      mutate_at(vars(matches("App")), ~.*transf_fact) %>%
      gather(y_var, val, -x) %>%
      ggplot(aes(x = as.factor(x), y = val, fill = y_var))  
      geom_col(data = . %>% filter(y_var == "Total_Wth"))  
      geom_line(data = . %>% filter(y_var != "Total_Wth"),
                aes(color = y_var, group = y_var),
                size = 1.2)  
      scale_fill_discrete(aesthetics = c("colour", "fill"))  
      scale_y_continuous(sec.axis = sec_axis(trans = ~ . / transf_fact, 
                                             name = "%", labels = scales::percent))  
      labs(x = "Month")
    
    

The above code gives me:

enter image description here

CodePudding user response:

I think this does all you ask. The steps are

  1. Make sure you specify the factor levels when converting x to a factor. Assuming your data frame is ordered by date, this is as simple as factor(x, df$x)
  2. Increasing the y axis limits to c(0, 170000) will stretch both the primary and secondary axis, so you will get your 100% on the second axis 'for free' if you simply increase the primary axis limits.
  3. Assuming you actually want the label 170,000 to appear as the uppermost break on the y axis, you would need to manually add breaks, as 170,000 is not likely to be a tick added as a pretty break. You can manually specify the breaks to be whatever you want. If you don't need the upper axis tick to say 170,000 but just have the plot tall enough to include that value if it is present, then point (2) already has you covered here.
df %>%
  mutate_at(vars(matches("App")), ~.*transf_fact) %>%
  gather(y_var, val, -x) %>%
  ggplot(aes(x = factor(x, df$x), y = val, fill = y_var))  
  geom_col(data = . %>% filter(y_var == "Total_Wth"))  
  geom_line(data = . %>% filter(y_var != "Total_Wth"),
            aes(color = y_var, group = y_var),
            size = 1.2)  
  scale_fill_discrete(aesthetics = c("colour", "fill"))  
  scale_y_continuous(sec.axis = sec_axis(trans = ~ . / transf_fact, 
                                         name = "%", 
                                         labels = scales::percent),
                     limits = c(0, 170000), 
                     breaks = c(34000 * 0:5))  
  labs(x = "Month")

enter image description here

  •  Tags:  
  • r
  • Related