ggplot绘制20个温度面板图时数值偏移问题求助
修复ggplot多面板温度图的数值偏移问题
问题描述
尝试用ggplot绘制1996-2015年共20年7-10月每日温度的20个面板图(x轴为日期,y轴为温度),但生成的面板中温度值出现偏移,仅展示1996-2006年的10个面板作为示例。
数据预览
dput(head(atlanta_temp_data))输出如下:
structure(list(DAY = structure(c(19539, 19540, 19541, 19542, 19543, 19544), class = "Date"), X1996 = c(98L, 97L, 97L, 90L, 89L, 93L), X1997 = c(86L, 90L, 93L, 91L, 84L, 84L), X1998 = c(91L, 88L, 91L, 91L, 91L, 89L), X1999 = c(84L, 82L, 87L, 88L, 90L, 91L), X2000 = c(89L, 91L, 93L, 95L, 96L, 96L), X2001 = c(84L, 87L, 87L, 84L, 86L, 87L), X2002 = c(90L, 90L, 87L, 89L, 93L, 93L), X2003 = c(73L, 81L, 87L, 86L, 80L, 84L), X2004 = c(82L, 81L, 86L, 88L, 90L, 90L), X2005 = c(91L, 89L, 86L, 86L, 89L, 82L), X2006 = c(93L, 93L, 93L, 91L, 90L, 81L), X2007 = c(95L, 85L, 82L, 86L, 88L, 87L), X2008 = c(85L, 87L, 91L, 90L, 88L, 82L), X2009 = c(95L, 90L, 89L, 91L, 80L, 87L), X2010 = c(87L, 84L, 83L, 85L, 88L, 89L), X2011 = c(92L, 94L, 95L, 92L, 90L, 90L), X2012 = c(105L, 93L, 99L, 98L, 100L, 98L), X2013 = c(82L, 85L, 76L, 77L, 83L, 83L), X2014 = c(90L, 93L, 87L, 84L, 86L, 87L), X2015 = c(85L, 87L, 79L, 85L, 84L, 84L)), row.names = c(NA, 6L), class = "data.frame")
原代码
rm(list = ls()) library(data.table) library(ggplot2) set.seed(20) atlanta_temp_data=read.table("temps.txt",header=TRUE) atlanta_temp_data$DAY=as.Date(atlanta_temp_data$DAY,format="%d-%b") class(atlanta_temp_data$DAY) atlanta_temp_data$Year = rep(1996:2015, each=12)[1:nrow(atlanta_temp_data)] ggplot(atlanta_temp_data, aes(DAY, group = Year, color = Year)) + geom_line(aes(y = X1996, color = "X1996"))+ geom_line(aes(y = X1997, color = "X1997")) + geom_line(aes(y = X1998, color = "X1998")) + geom_line(aes(y = X1999, color = "X1999")) + geom_line(aes(y = X2000, color = "X2000")) + geom_line(aes(y = X2001, color = "X2001")) + geom_line(aes(y = X2002, color = "X2002")) + geom_line(aes(y = X2003, color = "X2003")) + geom_line(aes(y = X2004, color = "X2004")) + geom_line(aes(y = X2005, color = "X2005")) + geom_line(aes(y = X2006, color = "X2006")) + geom_line(aes(y = X2007, color = "X2007")) + geom_line(aes(y = X2008, color = "X2008")) + geom_line(aes(y = X2009, color = "X2009")) + geom_line(aes(y = X2010, color = "X2010")) + geom_line(aes(y = X2011, color = "X2011")) + geom_line(aes(y = X2012, color = "X2012")) + geom_line(aes(y = X2013, color = "X2013")) + geom_line(aes(y = X2014, color = "X2014")) + geom_line(aes(y = X2015, color = "X2015")) + geom_point(aes(y = X1996, color = "X1996"))+ geom_point(aes(y = X1997, color = "X1997")) + geom_point(aes(y = X1998, color = "X1998")) + geom_point(aes(y = X1999, color = "X1999")) + geom_point(aes(y = X2000, color = "X2000")) + geom_point(aes(y = X2001, color = "X2001")) + geom_point(aes(y = X2002, color = "X2002")) + geom_point(aes(y = X2003, color = "X2003")) + geom_point(aes(y = X2004, color = "X2004")) + geom_point(aes(y = X2005, color = "X2005")) + geom_point(aes(y = X2006, color = "X2006")) + geom_point(aes(y = X2007, color = "X2007")) + geom_point(aes(y = X2008, color = "X2008")) + geom_point(aes(y = X2009, color = "X2009")) + geom_point(aes(y = X2010, color = "X2010")) + geom_point(aes(y = X2011, color = "X2011")) + geom_point(aes(y = X2012, color = "X2012")) + geom_point(aes(y = X2013, color = "X2013")) + geom_point(aes(y = X2014, color = "X2014")) + geom_point(aes(y = X2015, color = "X2015")) + scale_color_discrete(name = "Year") + theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5))+ ggtitle("Atlanta temps for July to October (1996-2015)")+labs(y = "Temperature (degF)")+facet_wrap(~Year)
问题原因
- 数据格式不匹配:原数据是宽格式(每列对应一个年份),但ggplot需要长格式数据(每行对应一个日期-年份-温度观测),手动叠加所有年份的图层会导致每个面板显示所有年份数据,引发偏移。
- Year列生成错误:
rep(1996:2015, each=12)假设每年只有12天,与7-10月实际天数不符,导致年份分组错误,facet无法正确拆分面板。 - 日期处理不当:
as.Date(...)会给日期默认添加当前年份,导致x轴显示的日期包含无关年份信息,影响面板内的日期对齐。
修复方案
将数据转换为长格式,正确处理日期和年份,再用ggplot绘制:
rm(list = ls()) library(data.table) library(ggplot2) library(tidyr) # 用于宽转长 # 读取数据 atlanta_temp_data <- read.table("temps.txt", header = TRUE) # 处理日期:提取月日作为字符,避免默认年份干扰 atlanta_temp_data$DAY <- format(as.Date(atlanta_temp_data$DAY, format = "%d-%b"), "%b-%d") # 宽格式转长格式:将年份列转为Year和Temperature两列 temp_long <- pivot_longer(atlanta_temp_data, cols = starts_with("X"), # 选择所有以X开头的年份列 names_to = "Year", values_to = "Temperature", names_prefix = "X") # 去掉Year列的X前缀 # 转换Year为数值型 temp_long$Year <- as.numeric(temp_long$Year) # 绘制面板图 ggplot(temp_long, aes(x = DAY, y = Temperature, group = 1)) + geom_line(color = "steelblue") + geom_point(color = "darkred", size = 0.8) + facet_wrap(~Year, ncol = 5) + # 按年份分面,每行5个面板 theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5)) + ggtitle("Atlanta temps for July to October (1996-2015)") + labs(y = "Temperature (degF)", x = "Date")
代码说明
- 宽转长:用
pivot_longer将每个年份列转为Year和Temperature的键值对,符合ggplot的数据要求。 - 日期处理:将日期转为
月-日字符格式,确保所有年份的x轴日期对齐。 - 分面绘制:每个面板对应一个年份,
group=1确保每个面板内的日期按顺序连接成线。
内容的提问来源于stack exchange,提问作者Monu Singh
相关产品推荐
相关产品推荐

