ggplot2绘图x轴显示次月首日而非当月月末日期如何解决
问题描述
给定如下数据框df:
df <- structure(list(date = structure(c(19204, 19235, 19265, 19296), class = "Date"), value = c(3.5, 3.6, 4.05, 4.13)), row.names = c(NA, -4L), class = "data.frame")
数据内容如下:
date value 1 2022-07-31 3.50 2 2022-08-31 3.60 3 2022-09-30 4.05 4 2022-10-31 4.13
需求是让ggplot2绘制的折线图x轴展示date列的实际日期(即7-10月的当月最后一天),但设置scale_x_date()参数后,x轴刻度始终显示为次月首日,测试过的代码如下:
ggplot(data=df, aes(x=date, y=value)) + geom_line(linetype='solid', alpha = 1, size = 1.5, color='blue') + geom_point(alpha = 1, size = 4, color='blue') + # scale_x_date(limits = as.Date(c("2022-07-31", "2022-10-31"), format = '%Y-%m-%d'), breaks = '1 month') # scale_x_continuous(labels=format(as.Date(df$date), "%Y-%m-%d")) # scale_x_datetime(breaks = df$date, date_labels = '%Y-%m-%d') # scale_x_date(breaks = "1 month", minor_breaks = "1 month", date_labels = "%Y-%m-%d") scale_x_date(breaks = "1 month", minor_breaks = "1 month", date_labels = "%Y-%m-%d", limits = c(min(df$date), max = max(df$date)))

问题原因
scale_x_date()中传入breaks = "1 month"时,ggplot2默认以每月1日作为月刻度的计算锚点,自动生成间隔1个月的刻度序列,不会自动对齐数据中的月末日期,因此最终刻度会落在次月首日,和数据点位置错位。
解决方案
最直接的方式是显式指定刻度位置为数据中的实际日期,不要依赖自动间隔生成规则,修改后的代码如下:
ggplot(data=df, aes(x=date, y=value)) + geom_line(linetype='solid', alpha = 1, size = 1.5, color='blue') + geom_point(alpha = 1, size = 4, color='blue') + scale_x_date( breaks = df$date, # 直接使用数据中的日期作为x轴刻度 date_labels = "%Y-%m-%d", limits = range(df$date) # 轴范围取数据日期的最小、最大值即可 )
如果后续数据动态更新,需要自动生成对应区间的月末刻度,可以借助lubridate包自动计算月末日期作为刻度,无需手动绑定数据列:
library(lubridate) ggplot(data=df, aes(x=date, y=value)) + geom_line(linetype='solid', alpha = 1, size = 1.5, color='blue') + geom_point(alpha = 1, size = 4, color='blue') + scale_x_date( # 自动生成日期区间内所有月份的月末日期作为刻度 breaks = ceiling_date(seq(min(df$date), max(df$date), by = "month"), "month") - days(1), date_labels = "%Y-%m-%d", limits = range(df$date) )
修改后x轴刻度会精准对齐2022-07-31、2022-08-31、2022-09-30、2022-10-31四个数据点,不会再出现次月首日的错位刻度。
内容的提问来源于stack exchange,提问作者ah bon
相关产品推荐
相关产品推荐

