使用 ggplot 绘制具有不同起点和终点的时间序列数据时对月份间隔进行阴影处理
shading month intervals when plotting time series data with different start and end points using ggplot
我正在尝试使用 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))
我可以定义一个新的数据框对象,其中包含每个着色部分的起点和终点(即每年的 11 月至 3 月)
temp <- data.frame(
start = as.Date(c('2016-11-1', '2017-11-01', '2018-11-01', '2019-11-01')),
end = as.Date(c('2017-03-01', '2018-03-01', '2019-03-01', '2020-03-01')))
dateRanges <- data.frame(
start = as.POSIXct(temp [,1], "%Y-%m-%d")+ hours(6),
end = as.POSIXct(temp [,2], "%Y-%m-%d")+ hours(6))
然后画个图
ggplot(datOne) +
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)
虽然这对于单个时间序列来说效果很好,但我正在为许多单独的时间序列中的每一个制作一个单独的图形,每个时间序列都有不同的起点和终点,并且需要一个独特的数据框来创建阴影区域.
例如,如下图所示,将相同的 dateRanges
数据框应用于不同的时间序列显然不起作用。
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)
是否有不同的方法来遮蔽两个时间序列,以便我可以自动创建 dateRanges
或一起使用不同的方法(即注释...)。换句话说,鉴于需要在不同时期用 100 个不同的时间序列制作大约 100 个不同的数字,那么对任何给定年份从 11 月到 3 月的时间段进行阴影处理的最佳方法是什么?
提前致谢。
我不知道这是否是 "the best" 方法,但这是一个简单的方法:展开 dateRanges
框架并重置轴的限制:
# 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)
我正在尝试使用 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))
我可以定义一个新的数据框对象,其中包含每个着色部分的起点和终点(即每年的 11 月至 3 月)
temp <- data.frame(
start = as.Date(c('2016-11-1', '2017-11-01', '2018-11-01', '2019-11-01')),
end = as.Date(c('2017-03-01', '2018-03-01', '2019-03-01', '2020-03-01')))
dateRanges <- data.frame(
start = as.POSIXct(temp [,1], "%Y-%m-%d")+ hours(6),
end = as.POSIXct(temp [,2], "%Y-%m-%d")+ hours(6))
然后画个图
ggplot(datOne) +
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)
虽然这对于单个时间序列来说效果很好,但我正在为许多单独的时间序列中的每一个制作一个单独的图形,每个时间序列都有不同的起点和终点,并且需要一个独特的数据框来创建阴影区域.
例如,如下图所示,将相同的 dateRanges
数据框应用于不同的时间序列显然不起作用。
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)
是否有不同的方法来遮蔽两个时间序列,以便我可以自动创建 dateRanges
或一起使用不同的方法(即注释...)。换句话说,鉴于需要在不同时期用 100 个不同的时间序列制作大约 100 个不同的数字,那么对任何给定年份从 11 月到 3 月的时间段进行阴影处理的最佳方法是什么?
提前致谢。
我不知道这是否是 "the best" 方法,但这是一个简单的方法:展开 dateRanges
框架并重置轴的限制:
# 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)