如何在同比折线图中使用单日数据(R语言ggplot2实现)
问题描述
我有一份1989年至2023年的某地区日均气温数据集,示例数据如下:
DATE MAX ATT TEMP 1 1989-01-04 33.8 26.2 2 1989-01-06 41.0 29.6 3 1989-01-09 43.5 * 38.5 4 1989-02-05 39.6 * 35.6 5 1989-02-25 41.0 * 36.1 6 1989-02-26 49.1 40.6 7 1989-03-04 60.4 * 57.9 8 1989-03-07 63.3 49.8 9 1989-03-09 64.4 * 54.0 10 1989-03-13 55.4 * 46.5
需求是用TEMP变量绘制每年一条折线的单日粒度同比折线图,展示所有有记录的单日数据。但尝试过程中遇到两个问题:
- 初始ggplot2代码生成的图未按年份拆分折线,仅按年份着色
- 尝试按年中日(一年中的第几天)处理时,因闰年及数据非均匀分布失败
初始代码:
library(ggplot2) weather = read.csv("<FILE>") weather$MonthN <- as.numeric(format(as.Date(weather$DATE_FORMAT),"%m")) # Month's number weather$Month <- months(as.Date(weather$DATE_FORMAT), abbreviate=TRUE) # Month's abbr. weather$Year <- (format(as.Date(weather$DATE_FORMAT),"%Y")) # Year's number ggplot(data = weather, aes(x = DATE, y = TEMP, group=Year, shape = Year, colour=Year)) + geom_line() + labs(x="Month", colour="Year") + theme_classic()
解决方案
核心问题是初始代码用完整日期作为x轴,不同年份的日期是独立离散值,无法实现同比对齐。以下是修正后的实现:
library(ggplot2) library(dplyr) # 读取数据(替换为你的文件路径) weather <- read.csv("<FILE>", stringsAsFactors = FALSE) # 预处理日期:转换格式、生成同比对齐标识、处理闰年 weather <- weather %>% mutate( DATE = as.Date(DATE), # 生成统一的月-日字符串,作为同比对齐的x轴依据 day_label = format(DATE, "%m-%d"), # 将闰年2月29日映射到2月28日,避免孤立刻度 day_label = ifelse(day_label == "02-29", "02-28", day_label), Year = format(DATE, "%Y") ) # 绘制同比折线图 ggplot(data = weather, aes(x = day_label, y = TEMP, group = Year, colour = Year)) + geom_line(na.rm = TRUE) + # 优化x轴刻度:仅显示每月第一天,避免拥挤 scale_x_discrete( breaks = c("01-01", "02-01", "03-01", "04-01", "05-01", "06-01", "07-01", "08-01", "09-01", "10-01", "11-01", "12-01"), labels = c("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec") ) + labs(x = "日期", y = "日均气温", colour = "年份") + theme_classic() + # 可选:年份过多时将图例移至底部,避免遮挡 theme(legend.position = "bottom")
关键说明
- 同比对齐:用
%m-%d格式的字符串作为x轴,让不同年份的同一天在x轴上处于同一位置,实现折线的同比对比 - 闰年处理:将闰年的2月29日映射到2月28日,避免出现无其他年份数据的孤立刻度点
- 折线拆分:通过
group = Year确保每个年份的点连接成独立折线,colour = Year用于区分不同年份 - x轴优化:只保留每月第一天作为刻度,解决单日刻度过多导致的拥挤问题
内容的提问来源于stack exchange,提问作者wildkoala
相关产品推荐
相关产品推荐

