如何在ggplot中实现非地理形状内的圆形遮罩?
在ggplot中用自定义形状遮罩行列排列的圆形
好问题!你想要的这种遮罩效果,完全不用手动去做坐标对比,有两个非常实用的方法可以实现,我来给你详细说明:
方法一:用ggfx包实现视觉遮罩
ggfx是专门为ggplot提供图形特效的工具包,它的with_mask()函数可以轻松实现你要的遮罩效果——直接把圆形图层“套”在自定义形状里,外部的圆形会被自动隐藏。
步骤:
- 先安装并加载
ggfx包 - 把原来用线段画的形状改成填充多边形(因为遮罩需要一个闭合的填充区域)
- 用
with_mask()包裹你的点图层,指定遮罩图层为自定义多边形
完整代码:
library(tidyverse) library(ggfx) maxX <- 12 maxY <- 9 circles <- data.frame(circleNo = seq(1, maxX * maxY, 1) - 1) %>% mutate(x = circleNo %% maxX, y = floor(circleNo / maxX)) # 定义闭合形状(不用线段,直接用多边形数据) shape <- data.frame(x = c(1, 1, 7, 7, 11, 11, 6, 5, 3, 2, 1), y = c(1, 8, 7, 5, 5, 1, 3, 3, 3, 1, 1)) ggplot() + # 用with_mask包裹点图层,遮罩是自定义多边形 with_mask( geom_point(data = circles, aes(x = x, y = y), shape = 1, size = 9, fill = NA), mask = geom_polygon(data = shape, aes(x = x, y = y), fill = "white") ) + # 可选:画出形状轮廓 geom_polygon(data = shape, aes(x = x, y = y), color = "black", fill = NA) + theme_void() + coord_fixed(ratio = 1)
这个方法的优势是视觉层面直接遮罩,不需要修改原始的圆形数据,适合快速出图。
方法二:用sf包从数据层面过滤
如果你需要从数据上彻底移除形状外的圆形(而不是仅仅隐藏),可以用sf空间包来判断圆心是否在多边形内,然后过滤数据框。
步骤:
- 安装并加载
sf包 - 将自定义形状转成空间多边形对象
- 将圆形的圆心坐标转成空间点对象
- 用
st_within()判断哪些点在多边形内,过滤出符合条件的圆形
完整代码:
library(tidyverse) library(sf) maxX <- 12 maxY <- 9 circles <- data.frame(circleNo = seq(1, maxX * maxY, 1) - 1) %>% mutate(x = circleNo %% maxX, y = floor(circleNo / maxX)) # 定义闭合形状并转成sf多边形 shape_sf <- data.frame(x = c(1, 1, 7, 7, 11, 11, 6, 5, 3, 2, 1), y = c(1, 8, 7, 5, 5, 1, 3, 3, 3, 1, 1)) %>% st_as_sf(coords = c("x", "y")) %>% summarise(geometry = st_combine(geometry)) %>% st_cast("POLYGON") # 将圆形圆心转成sf点,判断是否在多边形内 circles_sf <- circles %>% st_as_sf(coords = c("x", "y")) %>% mutate(in_shape = st_within(geometry, shape_sf, sparse = FALSE)[,1]) %>% # 过滤出在形状内的点 filter(in_shape) %>% # 转回普通数据框(方便ggplot使用) st_drop_geometry() ggplot() + geom_point(data = circles_sf, aes(x = x, y = y), shape = 1, size = 9, fill = NA) + geom_polygon(data = shape_sf, aes(x = st_coordinates(geometry)[,1], y = st_coordinates(geometry)[,2]), color = "black", fill = NA) + theme_void() + coord_fixed(ratio = 1)
这个方法的优势是数据更干净,后续分析或修改图形时不需要考虑外部的圆形。
两种方法的选择
- 如果只是需要视觉效果,选
ggfx更简单快捷 - 如果需要处理数据(比如统计形状内的圆形数量),选
sf更合适
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

