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

使用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()

问题分析

报错的核心原因:

  1. DATE列是字符型而非时间格式,geom_contour_filled无法识别连续时间轴
  2. 原始CTD数据是离散剖面数据,geom_contour_filled需要规则网格数据才能生成填充等高线
  3. 默认y轴方向不符合海洋学绘图习惯(通常要求浅深度在上方,需反转y轴)
  4. 数据中存在异常值(如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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 05:05:57