Home > other >  How to insert text label on faceted time series data using the forecast package in R?
How to insert text label on faceted time series data using the forecast package in R?

Time:11-26

I am doing time series analysis in R using the forecast package. The forecast::autoplot() creates a ggplot object.

I have two questions about plotting decomposed series:

  1. How do I place text in the trend panel (next to the vertical red line). Using ggplot or other packages?
  2. How can I rename the "data" panel to be capitalized as "Data"?

Here is my code:

library(forecast)    

# Load in AirPassengers time series
data("AirPassengers")

# Decomopose time series
decomposed_ts <- decompose(AirPassengers)

# Plot decomposed time series
forecast::autoplot(decomposed_ts)   geom_vline(xintercept = 1954, colour = "red")

Screenshot of two questions

For Q1, I tried to use annotate() but it places the same text labels on each facet, whereas I only want one label on only the trend panel (see screenshot). I also tried to use the ggtext package, but could not get it to work. I couldn't figure out what the faceted variable is because forecast::autoplot() automatically created the faceting.

For Q2. I saved the plot as a variable i.e. myPlot <- forecast::autoplot(decomposed_ts) geom_vline(xintercept = 1954, colour = "red"). I then tried myPlot$ looking for where the "data" facet is named.

CodePudding user response:

I'm sure someone smarter than me could dig into the architecture of a ggplot2 plot, but you could make your own autoplot function to keep it a little simpler(ish). Here I added a facet label argument to solve your problem:

library(tidyverse)
library(forecast)    


my_new_autoplot <- function(decomp, 
                            facet_labels = c("data", "trend", "seasonal", "remainder")){
  list(
tibble(Time = time(decomp$x),
       val = decomp$x,
       type = facet_labels[1]),

tibble(Time = time(decomp$trend),
       val = decomp$trend,
       type = facet_labels[2]),

tibble(Time = time(decomp$seasonal),
       val = decomp$seasonal,
       type = facet_labels[3]),

tibble(Time = time(decomp$random),
       val = decomp$random,
       type = facet_labels[4]) |>
  mutate(t1 = pmax(0, val),
         t2 = pmin(val, 0),
         val = 0)
) |>
  bind_rows() |>
  mutate(type = factor(type, levels = facet_labels)) |>
  ggplot(aes(Time, val)) 
  geom_path() 
  geom_errorbar(aes(ymin = t2, ymax = t1)) 
  facet_wrap(~type, ncol = 1, scales = "free_y", strip.position = "left") 
  labs(y = "")
}

my_new_autoplot(decomposed_ts)   
  geom_vline(xintercept = 1954, colour = "red")

my_new_autoplot(decomposed_ts, 
                facet_labels = c("my_data!", "trend..", "~seasonal~", "rEmainDeR"))   
  geom_vline(xintercept = 1954, colour = "red")

And if we wanted to add text, we can do that too:

my_plot <- my_new_autoplot(decomposed_ts, 
                facet_labels = c("my_data!", "trend..", "~seasonal~", "rEmainDeR"))   
  geom_vline(xintercept = 1954, colour = "red")


add_text <- function(plot, facet, text, x, y, ...){
  text_data <- tibble(Time = x, val = y, type = facet, label = text) |>
    mutate(type = factor(type, levels = levels(plot$data$type)))
  
  plot 
    geom_text(data = text_data, aes(label = label), ...)
}

add_text(plot = my_plot, 
         facet = "rEmainDeR", 
         text = "This is red", 
         x = 1955, 
         y = 40,
         color = "red")

CodePudding user response:

You can add geom_text to the original auto_plot:

annotation <- data.frame(
  x = c(1950),
  y = c(250),
  parts = c("trend"),
  label = c("label 1")
)

forecast::autoplot(decomposed_ts)  
  geom_vline(xintercept = 1954, colour = "red")  
  geom_text(data = annotation, aes(x = x, y = y, label = label)) 

Adding a layer to autoplot

  • Related