You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)

问题原因

  1. 数据格式不匹配:原数据是宽格式(每列对应一个年份),但ggplot需要长格式数据(每行对应一个日期-年份-温度观测),手动叠加所有年份的图层会导致每个面板显示所有年份数据,引发偏移。
  2. Year列生成错误:rep(1996:2015, each=12)假设每年只有12天,与7-10月实际天数不符,导致年份分组错误,facet无法正确拆分面板。
  3. 日期处理不当: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 17:31:58