ggplot2 geom_ribbon 颜色标签时间序列

ggplot2 geom_ribbon to colour-label time series

我想使用 ggplot2 对时间序列进行颜色标记。我有两个不同的状态 (类),如下面的 labels 向量所示,我想将其叠加在 IBM Close 价格图之上。

以下是我的尝试,不幸的是,它无法按州生成独特的颜色编码区域。我主要在使用 geom_ribbon():

时遇到问题
library(TTR)
library(ggplot2)

data <- getYahooData("IBM", start = 20130101, end = 20150101, freq = "daily")
df <- data.frame(data)
df$Date <-as.Date(row.names(df),"%Y-%m-%d")        

# plot colour coded states on top of the original signal
dput(labels)
c(NA, NA, NA, NA, NA, NA, NA, NA, NA, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 2L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L)

# colour and class labels to be used by geom_ribbon
df_bg <- data.frame(x = c(0, rep(which(as.logical(diff(labels))), each=2), length(labels)), 
                    ymin = min(df$Close, na.rm = TRUE), 
                    ymax = 1.1*max(df$Close, na.rm = TRUE), 
                    fill = factor(rep(labels[c(which(as.logical(diff(labels))), length(labels) )], each=2))
                    )

ggplot(data=df) +
  geom_line(aes(x=1:nrow(df), y=diff_ma )) +
  labs(title="IBM 2-State HMM") +
  geom_ribbon(data = df_bg, 
              aes(x = x, ymin=ymin, ymax=ymax, fill=fill), alpha=.2) +
  xlab("Date") +
  ylab("Levels") +
  theme(legend.justification = c(1, 0), legend.position = c(1, 0))

正如您在下面看到的,此 geom_ribbon 代码生成了两者的混合,而不是截然不同的红色和蓝色填充区域。

我在这里做错了什么?我认为是 df_bg 中的 fill 列,但我不完全确定。另外,如果我想在 x 轴上按日期绘制,我还能使用 geom_ribbon 给标签上色吗?

P.S: 这个问题和我之前的问题有关.

您需要向您的数据和 geom_ribbon 调用添加一个 group 参数。否则它按颜色分组,并且只使用每种颜色的最小值到最大值的填充颜色。

# colour and class labels to be used by geom_ribbon
df_bg <- data.frame(x = c(0, rep(which(as.logical(diff(labels))), each=2), length(labels)), 
                    ymin = min(df$Close, na.rm = TRUE), 
                    ymax = 1.1*max(df$Close, na.rm = TRUE), 
                    fill = factor(rep(labels[c(which(as.logical(diff(labels))), length(labels) )], 
                                      each=2)),
                    grp = factor(rep(seq(sum(as.logical(diff(labels)), na.rm=TRUE)+1), each=2))
)
# 
ggplot(data=df) +
  geom_line(aes(x=1:nrow(df), y=Close)) +
  labs(title="IBM 2-State HMM") +
  geom_ribbon(data = df_bg, 
              aes(x = x, ymin=ymin, y=180, ymax=ymax, fill=fill, group=grp), alpha=.2) +
  xlab("Date") +
  ylab("Levels") +
  theme(legend.justification = c(1, 0), legend.position = c(1, 0))

编辑:为了将 x-axis 更改为 Date 格式,您可以在 geom_line 命令中使用 Date 并更改 df_bgDate

# colour and class labels to be used by geom_ribbon
df_bg <- data.frame(x = df[c(1, rep(which(as.logical(diff(labels))), each=2), length(labels)), "Date"], 
                    ymin = min(df$Close, na.rm = TRUE), 
                    ymax = 1.1*max(df$Close, na.rm = TRUE), 
                    fill = factor(rep(labels[c(which(as.logical(diff(labels))), length(labels) )], 
                                      each=2)),
                    grp = factor(rep(seq(sum(as.logical(diff(labels)), na.rm=TRUE)+1), each=2))
)
#
ggplot(data=df) +
  geom_line(aes(x=Date, y=Close)) +
  labs(title="IBM 2-State HMM") +
  geom_ribbon(data = df_bg, 
              aes(x = x, ymin=ymin, y=180, ymax=ymax, fill=fill, group=grp), alpha=.2) +
  xlab("Date") +
  ylab("Levels") +
  theme(legend.justification = c(1, 0), legend.position = c(1, 0))