更改ggplot中时间序列间隙的线型
Changing the line type of the gap in timeseries in ggplot
我有一个不规则间隔时间序列的水质测量值(通常每月测量一次,但不完全在每个月的同一天测量)。我用下面的代码在令人惊叹的 ggplot 中绘制了这些,用一条线连接所有测量值。
然而,当几个月没有进行测量时,也存在差距。我想用另一种线型或颜色绘制这些点之间的线(例如,如果间隔大于 60 天,则为虚线和灰色)。我需要为此拆分我的数据吗?我该如何处理?
library(ggplot2)
library(lubridate)
xdate <- as.Date(c(seq.POSIXt(ymd("2005-01-01"), ymd("2007-03-04"), by = "30 days"),
seq.POSIXt(ymd("2007-07-03"), ymd("2007-12-31"), by = "28 days"),
seq.POSIXt(ymd("2008-05-15"), ymd("2010-10-10"), by = "25 days"),
seq.POSIXt(ymd("2012-01-01"), ymd("2014-12-31"), by = "31 days")))
set.seed(321)
df <- data.frame(date = rep(xdate,3), par=rep(c("Cl","PO4","NO3")), y=rnorm(318,1,0.2))
ggplot(df, aes(x=date, y=y)) +
geom_point(size=2) +
geom_line() +
facet_wrap(~par, nrow=3)
这应该会让你接近,
library(dplyr)
df <- df %>% group_by(par) %>%
arrange(date) %>%
mutate(gap = cumsum(c(0, diff(date) > 60)))
ggplot(df, aes(x=date, y=y, colour=factor(gap))) +
geom_point(size=2) +
geom_line() +
facet_wrap(~par, nrow=3)
摆弄每个组的 ID 和 start/end 点应该能够将变量映射到线型。
在 baptiste 的帮助下,我找到了解决办法。也许数据操作可以更干净(欢迎提出建议),但它工作正常。
library(ggplot2)
library(lubridate)
library(dplyr)
#first some data
xdate <- as.Date(c(seq.POSIXt(ymd("2005-01-01"), ymd("2007-03-04"), by = "30 days"),
seq.POSIXt(ymd("2007-07-03"), ymd("2007-12-31"), by = "28 days"),
seq.POSIXt(ymd("2008-05-15"), ymd("2010-10-10"), by = "25 days"),
seq.POSIXt(ymd("2012-01-01"), ymd("2014-12-31"), by = "31 days")))
set.seed(321)
df <- data.frame(date = rep(xdate,3), par=rep(c("Cl","PO4","NO3")), y=rnorm(318,1,0.2))
# then calculate groups with dplyr (credits to @baptiste)
df <- df %>% group_by(par) %>%
arrange(date) %>%
mutate(gap = cumsum(c(0, diff(date) > 60)))
# extract the first and the last of every group
thefirst <-
df %>% group_by(gap,par) %>%
arrange(date) %>%
summarise(first(date),first(y))
thelast <-
df %>% group_by(gap,par) %>%
arrange(date) %>%
summarise(last(date),last(y))
# equalize colnames for rbind and ggplot
colnames(thefirst) <- colnames(thelast) <- colnames(df)[c(4,2,1,3)]
# add 1 to match with thelast of every group with the first of the next group
# and calculate max
thelast$gap <- thelast$gap+1
maxgap <- max(thelast$gap)
gaplines <- rbind(filter(thefirst, gap != 0), filter(thelast,gap != maxgap))
#ggplot the connected lines
(p <-
ggplot(df, aes(x=date, y=y)) +
geom_point(size=2) +
geom_line(aes(group=factor(gap))) +
facet_wrap(~par, nrow=3))
# add the dotted lines
p + geom_line(data=gaplines, aes(group = factor(gap)),linetype='dotted')
这给了我这张图:
我有一个不规则间隔时间序列的水质测量值(通常每月测量一次,但不完全在每个月的同一天测量)。我用下面的代码在令人惊叹的 ggplot 中绘制了这些,用一条线连接所有测量值。
然而,当几个月没有进行测量时,也存在差距。我想用另一种线型或颜色绘制这些点之间的线(例如,如果间隔大于 60 天,则为虚线和灰色)。我需要为此拆分我的数据吗?我该如何处理?
library(ggplot2)
library(lubridate)
xdate <- as.Date(c(seq.POSIXt(ymd("2005-01-01"), ymd("2007-03-04"), by = "30 days"),
seq.POSIXt(ymd("2007-07-03"), ymd("2007-12-31"), by = "28 days"),
seq.POSIXt(ymd("2008-05-15"), ymd("2010-10-10"), by = "25 days"),
seq.POSIXt(ymd("2012-01-01"), ymd("2014-12-31"), by = "31 days")))
set.seed(321)
df <- data.frame(date = rep(xdate,3), par=rep(c("Cl","PO4","NO3")), y=rnorm(318,1,0.2))
ggplot(df, aes(x=date, y=y)) +
geom_point(size=2) +
geom_line() +
facet_wrap(~par, nrow=3)
这应该会让你接近,
library(dplyr)
df <- df %>% group_by(par) %>%
arrange(date) %>%
mutate(gap = cumsum(c(0, diff(date) > 60)))
ggplot(df, aes(x=date, y=y, colour=factor(gap))) +
geom_point(size=2) +
geom_line() +
facet_wrap(~par, nrow=3)
摆弄每个组的 ID 和 start/end 点应该能够将变量映射到线型。
在 baptiste 的帮助下,我找到了解决办法。也许数据操作可以更干净(欢迎提出建议),但它工作正常。
library(ggplot2)
library(lubridate)
library(dplyr)
#first some data
xdate <- as.Date(c(seq.POSIXt(ymd("2005-01-01"), ymd("2007-03-04"), by = "30 days"),
seq.POSIXt(ymd("2007-07-03"), ymd("2007-12-31"), by = "28 days"),
seq.POSIXt(ymd("2008-05-15"), ymd("2010-10-10"), by = "25 days"),
seq.POSIXt(ymd("2012-01-01"), ymd("2014-12-31"), by = "31 days")))
set.seed(321)
df <- data.frame(date = rep(xdate,3), par=rep(c("Cl","PO4","NO3")), y=rnorm(318,1,0.2))
# then calculate groups with dplyr (credits to @baptiste)
df <- df %>% group_by(par) %>%
arrange(date) %>%
mutate(gap = cumsum(c(0, diff(date) > 60)))
# extract the first and the last of every group
thefirst <-
df %>% group_by(gap,par) %>%
arrange(date) %>%
summarise(first(date),first(y))
thelast <-
df %>% group_by(gap,par) %>%
arrange(date) %>%
summarise(last(date),last(y))
# equalize colnames for rbind and ggplot
colnames(thefirst) <- colnames(thelast) <- colnames(df)[c(4,2,1,3)]
# add 1 to match with thelast of every group with the first of the next group
# and calculate max
thelast$gap <- thelast$gap+1
maxgap <- max(thelast$gap)
gaplines <- rbind(filter(thefirst, gap != 0), filter(thelast,gap != maxgap))
#ggplot the connected lines
(p <-
ggplot(df, aes(x=date, y=y)) +
geom_point(size=2) +
geom_line(aes(group=factor(gap))) +
facet_wrap(~par, nrow=3))
# add the dotted lines
p + geom_line(data=gaplines, aes(group = factor(gap)),linetype='dotted')
这给了我这张图: