R 使用ggplot绘制具有不同起点和终点的时间序列数据时的着色月间隔
我正在尝试使用R 使用ggplot绘制具有不同起点和终点的时间序列数据时的着色月间隔,r,ggplot2,lubridate,R,Ggplot2,Lubridate,我正在尝试使用ggplot2中的geom_rect()为冬季月份遮荫,并且有许多不同的时间序列数据,具有不同的起点和终点。对于每个时间序列,我希望从每年的11月到3月这段时间被着色(剩下的几个月应该不着色) 例如,使用以下时间序列 library(ggplot2) library(lubridate) now <- Sys.time() set.seed(123) datOne <- data.frame(IndID = "One", D
ggplot2
中的geom_rect()
为冬季月份遮荫,并且有许多不同的时间序列数据,具有不同的起点和终点。对于每个时间序列,我希望从每年的11月到3月这段时间被着色(剩下的几个月应该不着色)
例如,使用以下时间序列
library(ggplot2)
library(lubridate)
now <- Sys.time()
set.seed(123)
datOne <- data.frame(IndID = "One",
DateTime = seq(from = now - dyears(0.2), length.out = 50, by = "months"),
Value = rnorm(50))
虽然这适用于单个时间序列,但我正在为每个单独的时间序列制作一个单独的图形,每个时间序列都有不同的起点和终点,并且需要一个唯一的数据帧来创建着色区域。
例如,如下图所示,应用于不同时间序列的相同日期范围
数据帧显然不起作用
datTwo <- data.frame(IndID = "Two",
DateTime = seq(from = now , length.out = 100, by = "months"),
Value = rnorm(100))
ggplot(datTwo) +
geom_rect(data = dateRanges, aes(xmin = start , xmax = end, ymin = -Inf, ymax = Inf),
inherit.aes=FALSE, alpha = 0.4, fill = c("lightblue"))+
geom_line(aes(x= DateTime, y = Value), size = 1.5)
datwo我不知道这是否是“最好”的方法,但这是一个简单的方法:扩展您的日期范围
帧并重置轴的限制:
# let's make it past & future proof for the next few years:
dateRanges <- data.frame(
start = seq(as.POSIXct("1900-11-01 07:00:00"), as.POSIXct("2100-11-01 07:00:00"), "1 year"),
end = seq(as.POSIXct("1901-03-01 07:00:00"), as.POSIXct("2101-03-01 07:00:00"), "1 year")
)
ggplot(datTwo) +
geom_rect(data = dateRanges, aes(xmin = start , xmax = end, ymin = -Inf, ymax = Inf),
inherit.aes=FALSE, alpha = 0.4, fill = c("lightblue"))+
geom_line(aes(x= DateTime, y = Value), size = 1.5) +
coord_cartesian(xlim = range(datTwo$DateTime))
#让我们在接下来的几年里证明这一点:
dateRanges试试这个:
# make it a function
get.date.ranges <- function(data) {
range.df <- NULL
for (year in seq(min(year(data$DateTime)), year(max(data$DateTime)), 1)) {
cur <- data.frame(
start = as.POSIXct(as.Date(paste(year, '-11-1',sep='')), "%Y-%m-%d")+ hours(6),
end = as.POSIXct(as.Date(paste(year+1, '-03-1',sep='')), "%Y-%m-%d")+ hours(6)
)
if (cur$start <= max(data$DateTime)) {
range.df <- rbind(range.df, cur)
}
}
if (nrow(range.df) > 0) {
range.df[1,]$start <- max(range.df[1,]$start, min(data$DateTime))
range.df[nrow(range.df),]$end <- min(range.df[nrow(range.df),]$end, max(data$DateTime))
}
return(range.df)
}
# plot function
plot.data <- function(data) {
ggplot(data) +
geom_rect(data = get.date.ranges(data), aes(xmin = start , xmax = end, ymin = -Inf, ymax = Inf),
inherit.aes=FALSE, alpha = 0.4, fill = c("lightblue"))+
geom_line(aes(x= DateTime, y = Value), size = 1.5)
}
plot.data(datOne)
# let's make it past & future proof for the next few years:
dateRanges <- data.frame(
start = seq(as.POSIXct("1900-11-01 07:00:00"), as.POSIXct("2100-11-01 07:00:00"), "1 year"),
end = seq(as.POSIXct("1901-03-01 07:00:00"), as.POSIXct("2101-03-01 07:00:00"), "1 year")
)
ggplot(datTwo) +
geom_rect(data = dateRanges, aes(xmin = start , xmax = end, ymin = -Inf, ymax = Inf),
inherit.aes=FALSE, alpha = 0.4, fill = c("lightblue"))+
geom_line(aes(x= DateTime, y = Value), size = 1.5) +
coord_cartesian(xlim = range(datTwo$DateTime))
# make it a function
get.date.ranges <- function(data) {
range.df <- NULL
for (year in seq(min(year(data$DateTime)), year(max(data$DateTime)), 1)) {
cur <- data.frame(
start = as.POSIXct(as.Date(paste(year, '-11-1',sep='')), "%Y-%m-%d")+ hours(6),
end = as.POSIXct(as.Date(paste(year+1, '-03-1',sep='')), "%Y-%m-%d")+ hours(6)
)
if (cur$start <= max(data$DateTime)) {
range.df <- rbind(range.df, cur)
}
}
if (nrow(range.df) > 0) {
range.df[1,]$start <- max(range.df[1,]$start, min(data$DateTime))
range.df[nrow(range.df),]$end <- min(range.df[nrow(range.df),]$end, max(data$DateTime))
}
return(range.df)
}
# plot function
plot.data <- function(data) {
ggplot(data) +
geom_rect(data = get.date.ranges(data), aes(xmin = start , xmax = end, ymin = -Inf, ymax = Inf),
inherit.aes=FALSE, alpha = 0.4, fill = c("lightblue"))+
geom_line(aes(x= DateTime, y = Value), size = 1.5)
}
plot.data(datOne)
plot.data(datTwo)