使用geom_contour_filled绘制海洋温深剖面图的RStudio技术求助
解决RStudio中绘制海洋温深时间填充等高线图的问题
我有一份约12万行的海洋学CSV数据集,想要在RStudio中绘制类似ODV(Ocean Data View)的温深时间填充等高线图。用geom_contour_filled尝试绘图时报错,看不懂错误信息,目前只能画出不符合需求的折线图,求解决。
数据集样例
#Data DATE;HEURE;nomSite*;gpsLong*;gpsLat*;TEMPERATURE;FLUORESCENCE;PAR;SALINITE;PROFONDEUR 11/04/1996;08:52:41;Frioul;5.29167;43.2417;13.5600;0.1160;999999;37.9900;0.60 11/04/1996;08:52:34;Frioul;5.29167;43.2417;13.5500;0.1300;999999;37.9800;2.10 ...(其余数据省略)
报错代码
library(ggplot2) somlit <- read.csv("Somlit_Extraction_ctd_frioul.csv", sep=";", dec = ".") somlit <- na.omit(somlit) ggplot(somlit, aes(x = DATE, y = PROFONDEUR, z = TEMPERATURE, fill = TEMPERATURE)) + geom_contour_filled(color = "black") + scale_fill_viridis_c(name = "Température (°C)") + labs(x = "Date", y = "Profondeur (m)", fill = "Température (°C)") + theme_minimal()
当前可运行但不符合需求的代码
library(ggplot2) somlit_temp <- read.csv("Somlit_Extraction_ctd_frioul.csv", sep=";") ggplot()+ geom_line(data = somlit, aes(x = DATE, y = PROFONDEUR, color = TEMPERATURE))+ scale_colour_viridis_c()
问题分析
报错的核心原因:
DATE列是字符型而非时间格式,geom_contour_filled无法识别连续时间轴- 原始CTD数据是离散剖面数据,
geom_contour_filled需要规则网格数据才能生成填充等高线 - 默认y轴方向不符合海洋学绘图习惯(通常要求浅深度在上方,需反转y轴)
- 数据中存在异常值(如
PAR列的999999),可能干扰插值计算
解决方案
1. 数据预处理
先处理数据格式与异常值:
library(ggplot2) library(dplyr) library(lubridate) # 读取数据,保留小数格式 somlit <- read.csv("Somlit_Extraction_ctd_frioul.csv", sep=";", dec = ".") # 合并日期与时间为连续时间格式 somlit$datetime <- dmy_hms(paste(somlit$DATE, somlit$HEURE)) # 过滤温度异常值(根据海洋温度合理范围调整) somlit <- somlit %>% filter(TEMPERATURE > 0 & TEMPERATURE < 30) %>% na.omit() # 反转深度,让浅深度在y轴上方(符合海洋学绘图习惯) somlit$depth_rev <- -somlit$PROFONDEUR
2. 插值生成规则网格并绘图
使用akima包对离散数据插值,转换为规则网格后绘制填充等高线:
library(akima) library(tidyr) # 生成规则网格插值数据 interp_result <- interp(x = as.numeric(somlit$datetime), y = somlit$depth_rev, z = somlit$TEMPERATURE, nx = 300, ny = 100) # nx/ny控制网格精度,可按需调整 # 转换为ggplot可用的数据框格式 interp_df <- as.data.frame(interp_result) %>% pivot_longer(cols = -x, names_to = "y", values_to = "temperature") %>% mutate(y = as.numeric(gsub("y", "", y)), datetime = as.POSIXct(x, origin = "1970-01-01")) # 绘制类似ODV的温深时间图 ggplot(interp_df, aes(x = datetime, y = y, fill = temperature)) + geom_tile() + # 填充色块 geom_contour(color = "black", size = 0.3) + # 叠加等高线 scale_fill_viridis_c(name = "Température (°C)", na.value = NA) + scale_y_continuous(labels = ~ -., name = "Profondeur (m)") + # 还原深度显示 scale_x_datetime(date_labels = "%Y-%m", date_breaks = "1 year") + # 调整时间标签格式 labs(x = "Date") + theme_minimal() + theme(axis.text.x = element_text(angle = 45, hjust = 1)) # 旋转x轴标签避免重叠
3. 简化方案(无需手动插值)
使用metR包的geom_contour_fill,自动处理离散数据的插值:
library(metR) ggplot(somlit, aes(x = datetime, y = depth_rev, z = TEMPERATURE)) + geom_contour_fill() + scale_fill_viridis_c(name = "Température (°C)") + scale_y_continuous(labels = ~ -., name = "Profondeur (m)") + scale_x_datetime(date_labels = "%Y-%m") + labs(x = "Date") + theme_minimal()
内容的提问来源于stack exchange,提问作者Lea
相关产品推荐
相关产品推荐

