首页 > 编程问答 >用 R 中的 ggmap 绘制 SpatRaster

用 R 中的 ggmap 绘制 SpatRaster

时间:2024-06-01 10:51:40浏览次数:28  
标签:r geospatial ggmap terra

感谢 这个 帖子,我已经能够计算出一些 KUD,并将其屏蔽到形状文件的区域中,然后使用 terra 软件包中的 ggplot SpatRaster 绘制这些图形

不过,我想将其映射到 ggmap 上。我当前的代码如下。

# 从 shapefile 创建 sf 对象,项目到 WGS84 UTM zone 31N/EPSG:32631
Abberton_utm <- st_read("WFD_Lake_Water_Bodies_Cycle_2.shp")%>%。
  st_as_sf() %>%
  st_transform(32631)

# 过滤数据以去除不准确的位置
AB_filt <- AB_DAT %>%
  dplyr::filter(HPE <= 2)

# 绘制 KUD 数据的代码
AB_KUD <- AB_filt %>%
  dplyr::arrange(Transmitter, DateTime) %>%
  #dplyr::filter(week == "24") %>%
  dplyr::select(Species, X_UTM, Y_UTM)

coordinates(AB_KUD) <- c("X_UTM","Y_UTM")
crs(AB_KUD) <- "EPSG:32631";

# 创建 estUDm 对象
kud <- kernelUD(AB_KUD[,1], h = "href") # href = 引用带宽

# 为 rasterize() 创建 SpatRaster 模板
# 只需执行一次,无需在循环中复制
r <- rast(ext(Abberton_utm), ncol = 100, nrow = 100, crs = "EPSG:32631")

# 从 kud 中创建第 95 百分位数多边形 sf,用于初始 ggplot()
sf_poly <- getverticeshr(kud, percent = 95) %>%
  st_as_sf() %>%
  st_set_crs(32631)

# 将 sf_poly 转换为 SpatRaster,裁剪并屏蔽为 Abberton_utm
tmpr <- terra::rasterize(sf_poly, r) %>%
  crop(., Abberton_utm, mask = TRUE)

# 为 tmpr 中的单元格分配百分位值
tmpr[] <- ifelse(is.na(tmpr[]), NA, 95)

# 创建初始图表
p <- ggplot() +
  geom_spatraster(data = tmpr, show.legend = FALSE)

这只是计算 95% 的 KUD,并使用 ggplot 对其进行映射。不过,我希望用下面的代码在 ggmap 上绘制。

# 您获取地图的代码
Abberton_eastern <- c(0.875, 51.827)
AbRes <- get_map(location=Abberton_eastern, source="google", maptype='stamen_terrain', zoom=14)

随后,我使用了一个循环,该循环以 5% 的间隔计算 KUD,并将它们叠加在绘图中。但是,我似乎无法实现第一步。复制我的代码所需的所有数据都在 这里


明白了!你想在ggmap上叠加使用 adehabitatHR 生成的核密度估计(KDE)图,而不是ggplot。这是一个实现目标的细分方法,以及克服你面临障碍的代码示例:

1. 投影对齐

  • ggmap使用WGS84(EPSG:4326): ggmap从Google地图或Stamen设计等来源获取地图图块,这些地图图块使用WGS84坐标系。
  • 将你的空间数据转换为WGS84: 使用 st_transform() Abberton_utm sf_poly 和用于创建 tmpr 栅格的范围转换为EPSG:4326。

2. 从栅格到数据框进行ggmap兼容性

  • ggmap使用 geom_tile geom_raster 这些geoms需要一个具有经度、纬度和值的data.frame。
  • 转换你的栅格: 使用 as.data.frame(rasterToPoints(tmpr)) tmpr 栅格转换为适合ggmap的data.frame。

3. 在循环中绘制

  • 针对每个百分比级别迭代: 在你的循环中,为每个KDE百分比级别创建单独的栅格,将其投影到WGS84,并转换为data.frame。
  • 使用 geom_tile geom_raster 添加图层: ggmap() 图上使用这些data.frame来叠加你的KDE。

代码示例

library(sf)
library(raster)
library(ggmap)
library(adehabitatHR)
library(terra)

# ...(你的数据加载和预处理代码)...

# 1. 投影对齐
Abberton_WGS84 <- st_transform(Abberton_utm, crs = 4326) 

# 2. 创建一个函数来准备ggmap的栅格
raster_for_ggmap <- function(sf_polygon, raster_template, percentile) {
  tmpr <- terra::rasterize(sf_polygon, raster_template) %>%
    crop(., Abberton_WGS84, mask = TRUE)
  tmpr[] <- ifelse(is.na(tmpr[]), NA, percentile)

  # 转换为WGS84
  tmpr_WGS84 <- project(tmpr, "+init=epsg:4326")

  # 转换为data.frame
  as.data.frame(rasterToPoints(tmpr_WGS84))
}

# 3. 使用ggmap绘制
# 获取地图
Abberton_eastern <- c(0.875, 51.827)
AbRes <- get_map(location = Abberton_eastern, source = "google", 
                 maptype = 'stamen_terrain', zoom = 14)

# 创建基本ggmap
p <- ggmap(AbRes)

# 循环并添加KDE图层
percentages <- seq(5, 95, by = 5) # 设置要绘制的百分比级别

for (perc in percentages) {

  # 为当前百分比创建sf多边形
  sf_poly <- getverticeshr(kud, percent = perc) %>%
    st_as_sf() %>%
    st_set_crs(32631) %>%
    st_transform(crs = 4326) # 转换为WGS84

  # 为ggmap准备栅格
  df_raster <- raster_for_ggmap(sf_poly, r, perc)

  # 使用geom_tile添加KDE图层
  p <- p +
    geom_tile(data = df_raster, aes(x = x, y = y, fill = layer), alpha = 0.5) 
}

# 自定义和显示最终图
p + 
  scale_fill_gradient(name = "KDE Percentile", low = "transparent", high = "blue") +
  labs(title = "Kernel Density Estimation on ggmap") 

这将创建一个ggmap,其中叠加了表示不同KDE百分比级别的多个半透明图层。调整颜色、透明度和整体美学以适合你的可视化偏好。

其他提示:

  • 性能: 对于大量百分比级别或高分辨率栅格,此过程可能需要一段时间才能绘制。考虑在循环外预处理栅格以提高效率。
  • tmap 包: 如果你想探索绘制空间数据的其他选项, tmap 包提供了一种强大且灵活的方法来创建具有多个图层的静态和交互式地图。

祝你的ggmap KDE可视化好运!

标签:r,geospatial,ggmap,terra
From: 78539515

相关文章

  • 用 pytorch 从零开始实现单隐层 MLP
    我的代码如下:importtorchfromtorchvisionimporttransformsfromtorch.utilsimportdata导入torchvision#==============load数据集defget_dataloader_workers():返回4defload_data_fashion_mnist(batch_size,resize=None):trans=[transforms.ToT......
  • 记一次NoResourceFoundException: No static resource异常
    org.springframework.web.servlet.resource.NoResourceFoundException:Nostaticresource是Controller层,Rest接口的定义错误ApiPost工具访问,调用接口报错改为@RestController注解......
  • flutter 空安全、late延迟及required关键词
    空安全Dart和Kotlin一样都是支持空安全,空安全操作符主要有两个:?可空类型!类型断言可空类型在之前我们的介绍中,声明一个变量,如:Stringstr="A";str=null;这个时候str=null代表会报错,提示Avalueoftype'Null'can'tbeassignedtoavariableoftype'String......
  • Spring Boot集成sse实现chatgpt流式交互
    1.什么是sse?SSE(Server-SentEvents)是一种允许服务器向客户端推送实时数据的技术,它建立在HTTP和简单文本格式之上,提供了一种轻量级的服务器推送方式,通常也被称为“事件流”(EventStream)。他通过在客户端和服务端之间建立一个长连接,并通过这条连接实现服务端和客户端的消息实......
  • MyBatis中insert和insertSelective的区别
    一、本文简介主要对比了MyBatis生成的Mapper类中的insert方法和insertSelective方法的区别二、insert和insertSelective的区别insert和insertSelective是MyBatis中用于插入数据到数据库的两种方法,它们之间的主要区别在于对null值的处理方式。insert:这个方法会将实体类......
  • 如何将 Langfuse 链接到自有 PostgreSQL 数据库并升级 PostgreSQL 版本
    在本文中,我们将介绍如何将Langfuse应用程序链接到自有的PostgreSQL数据库,并升级PostgreSQL以支持jsonb类型。前提条件运行CentOS7的服务器已安装的PostgreSQL9.2或更低版本需要将Langfuse连接到自有数据库,并升级PostgreSQL以支持jsonb类型1.......
  • Alpine Linux apk add DNS lookup error
    起因最近做了需要做几个基础镜像,Dockerfile来自Github某仓库,镜像使用的是AlpineLinux3.18,且这个镜像已经更改过软件包管理器apk所使用的软件包仓库(记住这句话),后面基于这个镜像我还需要额外加了一些其他软件包,Dockerfile大致如下FROM某个第三方镜像:alpine-3.18..........
  • Aspire初体验
    微服务新体验之Aspire初体验  合集-微服务(2) 1.微服务新体验之Aspire初体验05-302.Aspire项目发布到win11本地k8s集群05-31收起 安装aspire查看vs版本我这的版本是17.9.7,不支持aspire,所以需要升级更新VS点击帮助->检查更新点击更新静等安装升级......
  • flutter 监听网络HTTP数据流处理
    flutter网络用于HTTP的交互中,有Http和Dio两种方式,本次侧重介绍dio的简单使用1.flutter安装dio插件https://pub-web.flutter-io.cn/中搜索dio插件使用,详细安装如下:2.使用(1)创建CancelToken对象,可然后采用异步的方式进行数据post(本次交互使用post数据的方式),核心......
  • 50.Android网络编程的补充
    主要分为三点补充1.get和post方式请求访问网络记得一定要处理异常packagecom.example.four_content;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStream;importjava.io.InputStreamReader;importjava.io.OutputStream;importjav......