You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用ggplot2::geom_sf()裁剪ggplot2::geom_tile()图层?

用ggplot2的geom_sf裁剪geom_tile图层的优雅方案

你需要移除完全位于国家边界外的geom_tile瓦片,手动筛选行号的方法既繁琐又不可复用,这里提供基于空间分析的优雅解决方案:

解决方案思路

利用sf包的空间操作功能,将瓦片数据转换为空间对象后,通过空间交集判断自动筛选出与国家边界重叠(或中心位于境内)的瓦片,替代手动筛选。

方法1:基于瓦片中心点判断(简单高效)

如果瓦片分辨率足够高,判断中心点是否位于境内即可满足需求:

library(giscoR)
library(ggplot2)
library(sf)
library(dplyr)

# 获取意大利边界并统一坐标系统
country <- gisco_get_countries(country = "ITA") %>% 
  st_transform(crs = 4326)

# 生成瓦片数据
set.seed(42)
df <- expand_grid(long = seq(6, 19, length.out = 10),
                  lat = seq(35, 48, length.out = 10)) %>% 
  mutate(z = sample(100))

# 将瓦片数据转为SF点对象(以瓦片中心为空间点)
df_sf <- st_as_sf(df, coords = c("long", "lat"), crs = 4326)

# 筛选中心点位于意大利境内的瓦片
df_filtered <- df_sf %>%
  # 判断点是否在国家边界内
  st_within(country, sparse = FALSE) %>%
  as.data.frame() %>%
  rename(inside_country = V1) %>%
  bind_cols(df) %>%
  filter(inside_country)

# 绘图
ggplot() +
  geom_tile(data = df_filtered, aes(x = long, y = lat, fill = z)) +
  geom_sf(data = country, color = "red", fill = NA)

方法2:基于瓦片完整范围判断(精准)

如果需要严格移除完全位于境外的瓦片(即使中心点在境外但部分瓦片覆盖境内),可以创建瓦片的多边形范围,再判断是否与国家边界有交集:

library(giscoR)
library(ggplot2)
library(sf)
library(dplyr)
library(tidyr)

country <- gisco_get_countries(country = "ITA") %>% 
  st_transform(crs = 4326)

set.seed(42)
df <- expand_grid(long = seq(6, 19, length.out = 10),
                  lat = seq(35, 48, length.out = 10)) %>% 
  mutate(z = sample(100))

# 计算瓦片的半长(用于生成多边形边界)
delta_long <- diff(df$long)[1] / 2
delta_lat <- diff(df$lat)[1] / 2

# 为每个瓦片生成多边形空间对象
df_polygons <- df %>%
  rowwise() %>%
  mutate(
    tile_polygon = list(
      st_polygon(list(
        rbind(
          c(long - delta_long, lat - delta_lat),
          c(long + delta_long, lat - delta_lat),
          c(long + delta_long, lat + delta_lat),
          c(long - delta_long, lat + delta_lat),
          c(long - delta_long, lat - delta_lat)  # 闭合多边形
        )
      ))
    )
  ) %>%
  st_as_sf(crs = 4326)

# 筛选与意大利边界有交集的瓦片
df_filtered <- df_polygons %>%
  st_intersects(country, sparse = FALSE) %>%
  as.data.frame() %>%
  rename(has_intersection = V1) %>%
  bind_cols(df) %>%
  filter(has_intersection)

# 绘图
ggplot() +
  geom_tile(data = df_filtered, aes(x = long, y = lat, fill = z)) +
  geom_sf(data = country, color = "red", fill = NA)

方案优势

  • 无需手动指定行号,完全自动化筛选
  • 可直接复用在其他国家或不同分辨率的瓦片数据上
  • 空间判断逻辑精准,避免手动筛选的误差

内容的提问来源于stack exchange,提问作者David

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 13:07:36