在地图上绘制插值数据

时间:2012-04-06 18:50:52

标签: r maps ggplot2 automap spatial-interpolation

我在美国切萨皮克湾的不同地点拍摄了物种丰富度的调查数据,我想以图形方式将数据显示为“热图”。

我有一个lat / long坐标和丰富度值的数据框,我将其转换为SpatialPointsDataFrame并使用automap包中的autoKrige()函数生成插值。

首先,是否可以评论我是否正确实施autoKrige()功能?

其次,我无法绘制数据并覆盖该地区的地图。或者,我可以指定插值网格以反映Bay的边界(如建议here)吗?关于我如何做到这一点以及我可能从哪里得到这些信息的任何想法?将网格提供给autoKrige()似乎很容易。


编辑:感谢Paul的超级有用的帖子!这就是我现在拥有的。无法让ggplot接受插值数据和地图投影:

require(rgdal)
require(automap)
#Generate lat/long coordinates and richness data
set.seed(6)
df=data.frame(
  lat=sample(seq(36.9,39.3,by=0.01),100,rep=T),
  long=sample(seq(-76.5,-76,by=0.01),100,rep=T),
  fd=runif(10,0,10))
initial.df=df

#Convert dataframe into SpatialPointsDataFrame
coordinates(df)=~long+lat

#Project latlong coordinates onto an ellipse
proj4string(df)="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"
#+proj = the type of projection (lat/long)
#+ellps and +datum = the irregularity in the ellipse represented by planet earth

#Transform the projection into Euclidean distances
project_df=spTransform(df, CRS("+proj=merc +zone=18s +ellps=WGS84 +datum=WGS84")) #projInfo(type="proj")

#Perform the interpolation using kriging
kr=autoKrige(fd~1,project_df)
#Extract the output and convert to dataframe for easy plotting with ggplot2
kr.output=as.data.frame(kr$krige_output)
#Plot the output
#Load the map data for the Chesapeake Bay
cb=data.frame(map("state",xlim=range(initial.df$long),ylim=range(initial.df$lat),plot=F)[c("x","y")])

ggplot()+
  geom_tile(data=kr.output,aes(x=x1,y=x2,fill=var1.pred))+  
  geom_path(data=cb,aes(x=x,y=y))+
  coord_map(projection="mercator")

1 个答案:

答案 0 :(得分:47)

我对你的帖子有很多评论:

使用克里格

我看到您正在使用地统计学来构建热图。您还可以考虑其他插值技术,例如样条曲线(例如,字段包中的薄板样条曲线)。这些对数据的假设较少(例如平稳性),也可以很好地可视化您的数据。如果您将其发送到期刊,假设数量的减少可能会有所帮助,那么您就可以向审核人员解释。如果需要,您还可以比较一些插值技巧,有关提示,请参阅a report I wrote

数据投影

我看到你正在使用lat long坐标进行克里金法。 Edzer Pebesma(gstatremarked that的作者,没有适合拉特伦坐标的变差函数模型。这是因为在纬度上,距离不是直的(即Euclidean),而是在一个球体上(即Great circle distances)。没有协方差函数(或变差函数模型)对球坐标有效。我建议在使用automap之前使用spTransform包中的rgdal投影它们。

rgdal包使用proj4 projection library来执行计算。要投影数据,首先需要定义其投影:

proj4string(df) = "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"

上面表达式右侧的proj4字符串定义了投影的类型(+proj),使用的椭圆(+ellps)和基准面(+datum) 。要理解这些术语的含义,你必须将地球想象成一个土豆。地球不是完美的球形,这是由椭圆形定义的。地球也不是完美的椭圆体,但表面更不规则。这种不规则性由基准定义。另见this article on Wikipedia

定义投影后,您可以使用spTransform

project_df = spTransform(df, CRS("+proj= etcetc"))

其中CRS(“+ proj etc”)定义目标投影。哪种投影取决于您的地理位置和学习区域的大小。

使用ggplot2绘图

要向ggplot添加多边形或折线,请查看coord_map的文档。这包括使用maps包绘制国家边界的示例。如果您需要为学习区域加载例如shapefile,则可以使用rgdal进行加载。请记住,ggplot2适用于data.frame,而非SpatialPolygons。您可以使用以下内容将SpatialPolygons转换为data.frame

poly_df = fortify(poly_Spatial)

另请参阅我创建的this function以绘制空间网格。它直接适用于SpatialGrids / Pixels。请注意,您需要从该存储库(continuousToDiscrete)中获取一个或两个附加文件。

创建插值网格

我创建了automap,以便在未指定时生成输出网格。这是通过在数据点周围创建一个凸包,并在其中采样5000点来完成的。预测区域的边界以及在其中采样的点的数量(以及因此的分辨率)是非常随意的。对于特定应用,预测区域的形状可以从多边形导出,使用spsample来采样多边形内的点。取样的数量和分辨率取决于两件事:

  • 您拥有的数据类型,例如,如果您的数据非常流畅,那么与此平滑度相比,提高分辨率并没有多大意义。或者,如果您的数据有许多小规模的条纹,则需要高分辨率。如果您有观察支持这种高分辨率,那么这只是可能的。
  • 数据密度。如果您的数据更密集,则可以提高分辨率。

如果您使用插值地图进行后续分析,那么获得正确的分辨率非常重要。如果您纯粹将地​​图用于视觉目的,那么这一点就不那么重要了。但请注意,在这两种情况下,过高的分辨率可能会误导预测的准确性,而分辨率过低则无法确定数据的正确性。