使用terra::as.data.frame替代tidyterra::geom_spatraster时ggplot2坐标系错位问题
空间数据可视化中geom_raster与geom_spatraster的对齐问题
处理空间数据(矢量与栅格)可视化时,遇到了坐标系投影转换、数据范围转换相关的问题,核心表现为ggplot::geom_raster与tidyterra::geom_spatraster使用时的图层对齐差异:
以下代码使用tidyterra::geom_spatraster时,栅格与矢量位置匹配正常:
library(terra) library(sf) library(rnaturalearth) library(ggplot2) sf_use_s2(FALSE) x <- rast(nrows = 9, ncols = 18, nl = 3, xmin = 0, xmax = 360) v <- rep(as.vector(t(matrix(1:ncell(x), nrow = 9, ncol = 18))), 3) values(x) <- v v <- ne_coastline(scale = 50, returnclass = "sf") a <- vect(v) ggplot() + tidyterra::geom_spatraster(data = rotate(x[[1]])) + geom_sf(data = st_break_antimeridian(st_as_sf(a), lon_0 = 180)) + coord_sf( crs = "+proj=longlat +datum=WGS84 +lon_0=180", default_crs = sf::st_crs(4326), expand = FALSE )
但替换为geom_raster后,栅格位置错误,无法与矢量图层正确对齐,错误代码如下:
ggplot() + geom_raster(data = terra::as.data.frame(rotate(x[[1]]), xy = TRUE), aes(x = x, y = y, fill = lyr.1)) + geom_sf(data = st_break_antimeridian(st_as_sf(a), lon_0 = 180)) + coord_sf( crs = "+proj=longlat +datum=WGS84 +lon_0=180", default_crs = sf::st_crs(4326), expand = FALSE )
问题原因
tidyterra::geom_spatraster会自动读取栅格的空间元数据(坐标系、范围等),配合coord_sf完成正确的投影转换与位置映射geom_raster仅将data.frame中的x/y视为普通数值坐标,不识别空间元数据。rotate(x[[1]])后栅格经度范围为-180~180,但coord_sf指定的是+lon_0=180的坐标系(经度范围0~360,东半球0-180,西半球180-360),直接使用原始x值会导致坐标对应错误
解决方法
手动将栅格经度转换为+lon_0=180坐标系对应的范围(把-180~0的经度转为180~360),再传入geom_raster:
# 处理rotate后的栅格数据,转换经度范围 r_df <- terra::as.data.frame(rotate(x[[1]]), xy = TRUE) r_df$x <- ifelse(r_df$x < 0, r_df$x + 360, r_df$x) # 使用转换后的数据绘图 ggplot() + geom_raster(data = r_df, aes(x = x, y = y, fill = lyr.1)) + geom_sf(data = st_break_antimeridian(st_as_sf(a), lon_0 = 180)) + coord_sf( crs = "+proj=longlat +datum=WGS84 +lon_0=180", default_crs = sf::st_crs(4326), expand = FALSE )
内容的提问来源于stack exchange,提问作者Breeze
相关产品推荐
相关产品推荐

