时间序列中带有月份和日期的日期在 ggplot2 中绘制多年

Dates with month and day in time series plot in ggplot2 with facet for years

当在 ggplot2 中使用 facet 年时,我想在时间序列图的 x 轴中同时包含 monthday。我的 MWE 如下:

set.seed(12345)
Date <- seq(as.Date("2010/1/1"), as.Date("2014/1/1"), "week")
Y <- rnorm(n=length(Date), mean=100, sd=1)
df <- data.frame(Date, Y)

df$Year <- format(df$Date, "%Y")
df$Month <- format(df$Date, "%b")
df$Day <- format(df$Date, "%d")

df$MonthDay <- format(df$Date, "%d-%b")


p <- ggplot(data=df, mapping=aes(x=MonthDay, y=Y, shape=Year, color=Year)) + geom_point() +geom_line(aes(group = 1))
p <- p + facet_grid(facets = Year ~ ., margins = FALSE) + theme_bw()
print(p)

我尝试使用以下命令控制 x 轴标签

p + scale_y_continuous() + scale_x_date(labels = date_format("%d-%b"))

但它抛出以下错误信息。

Error: Invalid input: date_trans works with objects of class Date only

这似乎可以做到...我只是手动创建了标签...

library("ggplot2")
library("scales")
set.seed(12345)
Date <- seq(as.Date("2010/1/1"), as.Date("2014/1/1"), "week")
Y <- rnorm(n=length(Date), mean=100, sd=1)
df <- data.frame(Date, Y)

df$Year <- format(df$Date, "%Y")
df$Month <- format(df$Date, "%b")
df$Day <- format(df$Date, "%d")

df$MonthDay <- format(df$Date, "%d-%b")
df$MonthDay2 <- df$MonthDay
# only show every third label... otherwise it's too crowded
df$MonthDay2[as.numeric(row.names(df))%%3!=0] <- ""
labels <- df$MonthDay2

p <- ggplot(data=df, mapping=aes(x=MonthDay, y=Y, shape=Year, color=Year)) + geom_point() +geom_line(aes(group = 1))
p <- p + facet_grid(facets = Year ~ ., margins = FALSE) + theme_bw()
p + scale_y_continuous() + scale_x_discrete(labels=labels) + 
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, size = 8))

坚持使用您的代码@MYaseen208 来创建数据。

绘制时使用 x = Date 并使用下面的

p <- ggplot(data = df, aes(x = Date, y = Y, shape = Year, color = Year)) +
  geom_point() + geom_line(aes(group = 1))
  #adding facet and using facet_wrap with free x scales
  p <- p + facet_wrap(~Year,ncol=1, scales = "free_x") + theme_bw()+
scale_y_continuous() + 
scale_x_date(labels = date_format("%d-%b"), breaks = date_breaks("2 weeks")) +
 theme(axis.text.x = element_text(angle = 90, vjust = 0.5, size = 8))

我使用 facet_wrap,获得免费的 x_axis 体重秤。当您划分数据时,我们无法获得每年相同的日月组合。

你们很亲近。您希望 x 轴衡量您所在年份的位置,但您将其作为字符向量,因此要标记每个点。如果改为使用连续变量来表示它,则可以获得更好的结果。一个连续变量是一年中的第几天。

df$DayOfYear <- as.numeric(format(df$Date, "%j"))
ggplot(data = df,
       mapping = aes(x = DayOfYear, y = Y, shape = Year, colour = Year)) +
  geom_point() +
  geom_line() +
  facet_grid(facets = Year ~ .) +
  theme_bw()

可以使用适当的标签函数将轴的格式设置得更像日期,但仍然无法以非常符合日期的方式找到中断。 (除此之外,还有一个 NA 问题。)

ggplot(data = df,
       mapping = aes(x = DayOfYear, y = Y, shape = Year, colour = Year)) +
  geom_point() +
  geom_line() +
  facet_grid(facets = Year ~ .) +
  scale_x_continuous(labels = function(x) format(as.Date(as.character(x), "%j"), "%d-%b")) +
  theme_bw()

为了获得良好的日期中断的优点,可以使用不同的变量。一个与原始数据具有相同年份的日期,但只有一年。在这种情况下,2000 年是闰年。这个问题主要与闰日有关,但如果你不关心这个(非闰年的 3 月 1 日将与闰年的 2 月 29 日对齐,等等)你可以使用:

df$CommonDate <- as.Date(paste0("2000-",format(df$Date, "%j")), "%Y-%j")
ggplot(data = df,
       mapping = aes(x = CommonDate, y = Y, shape = Year, colour = Year)) +
  geom_point() +
  geom_line() +
  facet_grid(facets = Year ~ .) +
  scale_x_date(labels = function(x) format(x, "%d-%b")) +
  theme_bw()

对@Brian Diggs 保留原始日期和月份(3 月 1 日保留为 3 月 1 日而不是 2 月 29 日)的方法的修改是将日期强制转换为字符串,然后替换年份:

library(lubridate)
library(stringr)
df$CommonDate <- ymd(paste0("2000-",str_sub(as.character(df$Date),-5)))

然后您可以继续:

ggplot(data = df,
   mapping = aes(x = CommonDate, y = Y, shape = Year, colour = Year)) +
  geom_point() +
  geom_line() +
  facet_grid(facets = Year ~ .) +
  scale_x_date(labels = function(x) format(x, "%d-%b")) +
  theme_bw()