Search code examples
rggplot2time-seriesr-markdowntimeserieschart

Shaded area in ggplot2 with multiple time series in the same graph


I just need to insert an shaded small area in graph using ggplot2, like that

univariate_shaded_time_series

but I´m getting the following issue...

# R Packages

library(dplyr)
library(ggplot2)
library(plotly)

My dataset:

# Loading and visualizing data

multiple_time_series <- read.csv(file = "https://raw.githubusercontent.com/rhozon/datasets/master/timeseries_diff.csv", head = TRUE, sep = ";") %>%
  mutate(
    dates = as.Date(dates, format = "%d/%m/%y")
  ) %>% glimpse()

As you can see the dataset have the following time series v1, v2, v3, v4 and v5. Then I tryed to plot...

shade <- data.frame(
  x1 = "2022-05-04",
  x2 = "2022-05-05",
  y1 = 50, # Min y range
  y2 = 102  # Max y range
)

ggplotly(
  ggplot()+
  geom_line(aes(x = dates), data = multiple_time_series ) +
    geom_line(aes(y = v1), color = "black")+
    geom_line(aes(y = v2), color = "red")+
    geom_line(aes(y = v3), color = "blue")+
    geom_line(aes(y = v4), color = "green")+
    geom_line(aes(y = v5), color = "yellow")+
   geom_rect(data = shade, 
            mapping = aes(
              xmin = as.Date(x1),
              xmax = as.Date(x2),
              ymin = y1,
              ymax = y2), color = "blue", alpha = 0.5) + xlab("") +
  theme(axis.title.y = element_text(size = 7, angle = 90)) +
  ggtitle("Real data vs forecasted values")
)

And it return the following error message:

Error in FUN(X[[i]],...'v1' object didn´t found Calls <Anonimous>...<Anonimous> -> f -> scales_add_defaults -> lapply -> FUN
 

How can I add shade in my graph with multiple time series ?


Solution

  • I think you get that error because you only provided data = multiple_time_series to your first line layer. Subsequent layers don't have access to that data (and hence column 'v1' etc.), because the global data, that you can supply as ggplot(data = ...) is absent.

    You can simplify your plotting code if you reshape your data to have a long format, instead of a wide format.

    Moreover, you won't need to construct an extra data.frame if you just want to annotate a particular rectangle in the graph: the annotate() function is for these types of cases.

    library(dplyr)
    library(ggplot2)
    
    multiple_time_series <- read.csv(file = "https://raw.githubusercontent.com/rhozon/datasets/master/timeseries_diff.csv", head = TRUE, sep = ";") %>%
      mutate(
        dates = as.Date(dates, format = "%d/%m/%y")
      )
    
    df <- tidyr::pivot_longer(multiple_time_series, -dates)
    
    ggplot(df, aes(dates, value, colour = name)) +
      geom_line() +
      annotate(
        geom = "rect",
        xmin = as.Date("2022-05-04"),
        xmax = as.Date("2022-05-05"),
        ymin = -Inf, ymax = Inf,
        fill = "blue", alpha = 0.5
      )
    

    Created on 2022-05-07 by the reprex package (v2.0.1)