I can plot multiple simultaneous time series that undergo changepoints and regimes using ggplot2, and I can use colour to make the regimes clear (plotting different sections in different colors using geom_rect
). I need to produce a plot that makes it clear where the regimes are without the use of color. With three regimes it is possible to distinguish between the regimes using white, black and gray for shading, but it is difficult to tell them apart if more than three regimes are present.
I've put an example of a plot that I can make using color, I'd be very grateful if someone can suggest a plot that conveys the same information without the use of color.
library(ggplot2)
library(scales)
# generate 3 time series and store them in a data frame
generate_cp_ts <- function(tau, params) {
ts(c(arima.sim(model = list(ar = 0.2), n = tau[1], rand.gen = function(n) params[1] * rnorm(n)), arima.sim(model = list(ar = 0.2), n = tau[2] - tau[1], rand.gen = function(n) params[2] * rnorm(n)), arima.sim(model = list(ar = 0.2), n = tau[3] - tau[2], rand.gen = function(n) params[3] * rnorm(n)), arima.sim(model = list(ar = 0.2), n = tau[4] - tau[3], rand.gen = function(n) params[4] * rnorm(n))))
}
tau <- 100 * (1:4)
ts1 <- generate_cp_ts(tau, c(1.7, 0.3, 1.7, 1.7))
ts2 <- generate_cp_ts(tau, c(0.3, 2, 0.3, 0.9))
ts3 <- generate_cp_ts(tau, c(2, 2, 0.1, 0.7))
tsframe <- data.frame(ts = c(ts1, ts2, ts3), ts_level = factor(paste("Time Series", rep(1:3, each = 400))), time = rep(1:400, 3))
# Work out which colors are needed to color the plot and store in a data frame
CPs <- c(0, tau)
colour.frame <- data.frame(regime.from = rep(CPs[-length(CPs)], each = 3), regime.to = rep(CPs[-1], each = 3), ts_level = factor(paste("Time Series", rep(c(1:3), length(CPs) - 1))), regime = factor(c(0,0,0, 1,1,0, 0,0,1, 0,2,2) + 1))
# Plotting
qplot(x = time, y = ts, data = tsframe, facets = ts_level ~ ., alpha = I(1), geom = "line", ylab = "Time Series", xlab = "Time") +
geom_rect(aes(NULL, NULL, xmin = regime.from, xmax = regime.to, fill = regime), ymin = -6, ymax = 6, data = colour.frame) +
scale_fill_manual(values = alpha(c("blue", "red", "green"), 0.2))
After you created colour.frame
you can insert this code:
tdf <- colour.frame
tdf$xval <- (tdf$regime.from + tdf$regime.to)/2
tdf$yval <- max(tsframe$ts) * 0.8 # if 0.8 is higher (0.9) then the text is set higher
ggplot(tsframe, aes(x = time, y = ts)) +
geom_line() +
facet_grid(ts_level~.) +
geom_vline(xintercept = CPs) + # maybe play around with linetype
geom_text(aes(x = xval, y = yval, label = regime), data = tdf)