Search code examples
rggplot2axisstacked-chartmultiple-axes

Overlaying a line plot over a stacked bar plot with dual y axis


I tried many times to plot line data of temperature over a stacked bar chart, but it didn’t work. My data consists of four columns as shown below: site, Frequency, Movie _Status, and temperature:

Site Freq Moving _status Temp
Site_1 34. Totally_Moved. 30
Site_2 45. Partially_Moved 29
Site_3 55. Totally_Moved 29.5

Here is my code to generate the plot.

read.csv("Moving_site.csv")
Recovery_Status <- factor(sample(c("Totally_Moved", "Partially_Moved"),
                                 size = 50, replace = TRUE),
                          levels = c("Totally_Moved", "Partially_Moved")))

Frequency <- sample(0:100, size = 50, replace = TRUE)
Mean_Temp <- sample(0:50, size = 50, replace = TRUE)
Site <- c("Site_1”, “Site_2”, “Site_3”)

data<-read.table(file="Moving _site.txt", header=T)
data
ggplot(data=data, aes(x=Site, y=Frequency, fill=Moving _Status)) + geom_bar(stat ="identity")

ggplot(data, aes(fill=Moving _Status, y=Frequency, x=Site)) + 
  geom_bar(position="fill", stat="identity")  + scale_fill_grey() + scale_y_continuous() +
  ggtitle("Movement")+ 
  theme(plot.title = element_text(hjust = 0.5)) +  
  theme(axis.ticks = element_line(color = 2,
                                  linewidth = 2))


I want to add another y axis to represent the temperature. I tried to add temperature data as a line plot over the stacked bar chart I made already, but it doesn't show up. How can I add a line plot of temperature over the bar chart?

Solution

  • Here's an example with some faked data:

    library(tidyverse)
    set.seed(123)
    data <- data.frame(
      Recovery_Status = sample(
        c("Totally_Moved", "Partially_Moved"), 
        size = 50, replace = TRUE),
      Frequency = sample(0:100, size = 50, replace = TRUE),
      Site = sample(
        c("Site_1", "Site_2", 
          "Site_3"), 
        size = 50, replace = TRUE)
      )
    
    temps <- data.frame(
      Site = c(“Site_1”, “Site_2”, “Site_3”),
      Mean_Temp = sample(16:32, size = 7, replace = TRUE)
      )
    
    data <- left_join(data, temps, by = "Site")
    
    ggplot(data, aes(x = Site)) + 
      geom_bar(
        aes(fill = Moving_Status, y = Frequency), 
        position = "fill", stat = "identity"
        )  + 
      scale_y_continuous(
        sec.axis = sec_axis(
          ~ . * 50, 
          name = "Mean_Temp", 
          labels = scales::label_number(suffix = "ºC")
          )
      ) +
      scale_fill_grey() +
      geom_line(
        data = data %>% 
          mutate(
            temp_norm = scales::rescale(
              Mean_Temp, from = c(0,50), to = c(0, 1))
            ),
        aes(y = temp_norm, group = 1),
        color = "red3", linewidth = 1
      ) +
      ggtitle("Movement")+ 
      theme(plot.title = element_text(hjust = 0.5)) +  
      theme(axis.ticks = element_line(color = 2, linewidth = 2))