使用R对不规则网格上的二维/空间时间序列数据进行插值和绘图

3

这是我的第一篇文章,所以(i)我希望不会违反太多规则,(ii)需要将示例图形存储在外部。

我想要可视化不规则网格的时间序列数据,其中显示的参数也是地理度量(如纬度或水深)的函数。包含日期(date)、地理参数水深(dep)和感兴趣的参数盐度(sal)的示例数据文件以及使用 ggplot2 生成的初步散点图存储在我们的

owncloud

密码:timeseries

ggplot 绘图的R代码如下:

# Load required packages
library(ggplot2)
library(data.table)
library(colorRamps)
library(scales)

# Import spatial timeseries data
df      <- data.table(read.csv("timeseries_example.csv"))
df$date <- as.POSIXct(strptime(df$date, format="%m/%d/%Y", tz="GMT"))

# Scatterplot with color representing the z parameter

Fig <-
ggplot(data=df, aes(date, dep, col=Sal))+
  geom_point()+
  scale_y_reverse()+
  scale_colour_gradientn(colours = matlab.like2(7), oob=squish)

tiff("./example_timeseries_R_ggplot.tiff", width = 200, height = 100, 
  units =  'mm', res = 300, compression = 'lzw')
Fig
dev.off()

由于数据在空间和时间上不规则分布,使用ggplot的geom_tile()函数进行绘图需要插值。
免费软件Ocean Data View(ODV)可以进行这种插值操作,我希望能够用R复现存储在我们owncloud中的ODV图形(链接如上)。
由于这个问题类似于先前解决的问题,我尝试使用akima包将参数sal插值到更精细的日期和深度网格上。然而,由于x参数是POSIXct对象,这并没有起作用。
是否有人有解决方法?

我还没有检查过数据,只是一个想法。如果你使用 as.numeric 将 POSIXct 对象转换为数字,是否可以帮助你的插值? - www
感谢您的评论@ycw。确实,我尝试将POSIXct日期转换为数字。我必须将数字除以1e8,因为akima包要求x和y变量在4个数量级内(我不完全理解为什么)。然而,这种方法对我的数据集没有产生有意义的插值结果。 - Jens Daniel Müller
1个回答

6

我用过 MBA 套餐,效果很不错:

# Load required packages
library(ggplot2)
library(lubridate)
library(reshape2)
library(colorRamps)
library(scales)
library(MBA)

# Import spatial timeseries data
df      <- read.csv("timeseries_example.csv")
df$date <- as.POSIXct(strptime(df$date, format="%m/%d/%Y", tz="GMT"))
df$date <- decimal_date(df$date)

mba <- mba.surf(df[,c('date', 'dep', 'Sal')], 100, 100)
dimnames(mba$xyz.est$z) <- list(mba$xyz.est$x, mba$xyz.est$y)
df3 <- melt(mba$xyz.est$z, varnames = c('date', 'depth'), value.name = 'salinity')

Fig <-
  ggplot(data=df3, aes(date, depth))+
  geom_raster(aes(fill = salinity), interpolate = F, hjust = 0.5, vjust = 0.5) +
  geom_contour(aes(z = salinity)) + 
  geom_point(data = df, aes(date, dep), colour = 'white') +
  scale_y_reverse() +
  scale_fill_gradientn(colours = matlab.like2(7))
Fig

等高线图

有一些异常值,你可以通过插值设置进行清理。我只使用了默认设置。


@oropendola:非常感谢,您的解决方案完全符合我的要求!令我惊讶的是,在深度>225m处出现的小异常在运行您的代码时不存在。调整mba.surf函数中的参数nm有助于提高插值的质量,特别是当数据在空间和时间上的分辨率不同时。 - Jens Daniel Müller
@JensDanielMüller 如果这对您有用,请不要忘记通过单击答案本身左上方的勾号接受答案。 - AF7
我对mba包不熟悉,想知道如何在日期轴上进行插值。这该如何添加到代码mba <- mba.surf(df[,c('date', 'dep', 'Sal')], 100, 100) dimnames(mba$xyz.est$z) <- list(mba$xyz.est$x, mba$xyz.est$y) df3 <- melt(mba$xyz.est$z, varnames = c('date', 'depth'), value.name = 'salinity')中?谢谢 - Bill - Bill Perry
我不确定你所说的“沿日期轴”。它的工作与Akima包相同:在100 x 100网格(日期x深度)上插值盐度。这不是一个联合的一维插值... - oropendola

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接