绘图提高篇 | R-gstat-ggplot2 IDW计算及空间插值可视化

上一篇文章,我们使用了Python 自定义IDW插值函数进行了IDW空间插值及可视化的plotnine、Basemap的绘制方法,本期推文我们将使用R-gstat进行IDW插值计算和使用ggplot2进行可视化绘制,主要涉及的知识点如下:

  • R-gstat包IDW插值计算

  • R-ggplot2 IDW插值结果可视化绘制

R-gstat包IDW插值计算

得益于优秀且丰富的R语言第三方包,我们可以直接使用空间统计计算的R-gstat 包实现包括IDW在内的多种插值方法,使用R-sf包完美绘制空间可视化绘制。还是老样子,我们对所需数据(散点值+地图数据)的基本情况进行预览,结果如下:

绘图数据预览

  • 散点情况(scatter_df)

  • 地图文件(jiangsu)

    散点在地图上的可视化结果如下(之前推文已有过操作方法,不明白的小伙伴可以参考下):

gstat-IDW计算

接下来,我们使用gstat包进行IDW计算,在计算之前,我们需使用sp包对数据进行相关处理,具体操作如下:

将数据准换成空间数据格式:

sp::coordinates(scatter_df) = ~经度+纬度

数据格式准换如下:

「制作网格数据」: 更具地图文件的经纬度范围信息,我们进行网格(grid)的构建(我们需要插值的区域),代码如下:

sf::st_bbox(jiangsu)
#生成400*400的网格
grid <- expand.grid(x=seq(from = st_bbox(jiangsu)[1],to = st_bbox(jiangsu)[3],length.out = 400),
                    y=seq(from = st_bbox(jiangsu)[2],to = st_bbox(jiangsu)[4],length.out = 400))

这样就可以完成了400x400的网格点构建,接下来要将构建的网格点转换成空间数据格式,还是使用sp包操作,代码如下:

sp::coordinates(grid) <- ~x+y
sp::gridded(grid) <- TRUE

以上操作我们就完成了gstat包所需的所有数据处理操作。

「IDW 插值操作」

由于有现成的函数可以调用,这里我们直接使用,代码如下:

idw <- idw(formula = PM2.5 ~ 1,locations = scatter_df, newdata=grid)

解释如下:

  • formula = PM2.5~ 1 为固定样式,用于需要进行插值的纬度数据。

  • locations = scatter_df 为sp包处理过的样例点位置信息。

  • newdata=grid 为需要插值的网格大小,sp对象。 由于计算的idw结果较多(400*400),这里将其转换成df数据类型,同时对列进行重命名,也为以后的绘图提供方便,转换代码如下:

    idw_output <- as.data.frame(idw)
    names(idw_output)[1:3]<-c("long","lat","IDW_Result")

结果如下(部分):

ggplot2 可视化IDW插值结果

经过上面的数据规整,我们直接可以进行可视化操作,代码如下:

library(sf)
library(tidyverse)
library(ggspatial)
library(RColorBrewer)
library(ggtext)
library(hrbrthemes)

#自定义颜色
my_colormap <- colorRampPalette(rev(brewer.pal(11,'Spectral')))(32)
IDW_Map_title <- ggplot() + 
  geom_tile(data = idw_output,aes(x=long,y=lat,fill=IDW_Result)) +
  geom_sf(data = jiangsu,fill="NA",size=.5,color="gray40") +
  geom_sf(data = scatter_df_tro,aes(fill=PM2.5),shape=21,size=4,show.legend = FALSE)+
  scale_fill_gradientn(colours = my_colormap)+
  annotation_scale(location = "bl") +
      # spatial-aware automagic north arrow
       annotation_north_arrow(location = "tr", which_north = "false",
                             style = north_arrow_fancy_orienteering) +
  labs(
       title = "Map Charts in R Exercise 02: <span style='color:#D20F26'>Map IDW Interpolation</span>",
       subtitle = "processed map charts with <span style='color:#1A73E8'>geom_tile()</span>",
       caption = "Visualization by <span style='color:#DD6449'>DataCharm</span>") +
  theme_ipsum(base_family = "Roboto Condensed") +
  theme(
        plot.title = element_markdown(hjust = 0.5,vjust = .5,color = "black",
                             size = 20, margin = margin(t = 1, b = 12)),
        plot.subtitle = element_markdown(hjust = 0,vjust = .5,size=15),
        plot.caption = element_markdown(face = 'bold',size = 12),
  )

注意:这里我们将散点绘制在插值结果之上,也为了查看插值的效果,最终的可视化结果如下:

sf包裁剪操作

上面的可视化结果只是将网格插值结果全部绘制出来,没有将目标区域进行单独绘制(地图文件),这里使用sf::st_intersection() 函数进行实现"裁剪"操作,这里不再赘述,不明白的可以查看我之前的推文。最终的可视化结果如下:

注意: 小伙伴们可能也发现了,这样裁剪的结果不是完全的按照地图文件进行裁剪的,会有部分"溢出",特别是在绘制较大范围的空间图表的时候,这里可以转换成栅格数据,然后再使用*mask()*方法也是可以操作的,具体其他的,后面我会专门出一期推文介绍这两种"裁剪"操作的不同,这里先不做介绍。

总结

继上期我们推出Python 版本的IDW 空间插值之后,本期我们又推出了R版本的,大家可以对比下两种插值的结果(可能会存在些许的不同)。还是那句话,在绘制空间图表时,R因其完整的绘图体系及优秀的第三方包,可以较好的完成绘图需求(各种空间绘图元素的添加),但Python因其简单好学,也具有一定优势,大家可以选择适合自己的方法进行学习,至于对比两种语言绘图不同,就交给小编来做吧。下期,我们继续空间插值(克里金:Kriging)的计算及可视化绘制,还是Python和R的两个版本哦,大家敬请期待!

相关推荐
思麟呀33 分钟前
在C语言基础上的C++第二章(类和对象)
c语言·开发语言·c++·学习
怎么就重名了36 分钟前
python opencv的orb特征检测(Oriented FAST and Rotated BRIEF)
开发语言·python·opencv
技术小泽1 小时前
代码思想之快慢路径
java·开发语言·spring boot·后端·设计规范
tmacfrank1 小时前
Kotlin 协程基础知识总结三 —— 协程上下文与异常处理
开发语言·kotlin
江东飞过1 小时前
.net core 的文件操作
开发语言·后端·golang
久久不觉1 小时前
.net core 的字符串处理
开发语言·后端·golang
久久不觉1 小时前
.net core 的软件开发工具
开发语言·后端·golang
司马相楠1 小时前
.net core 的软件开发技能
开发语言·后端·golang
司马相楠1 小时前
.net core 的数据库编程
开发语言·后端·golang
龙晓飞度1 小时前
.net core 的函数实现
开发语言·后端·golang