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

如何将grid包创建的图案应用到geom_sf()中?

ggplot2 3.5.0中grid图案填充sf地理数据失败的问题解决

问题场景

使用ggplot2 3.5.0新增的图案填充功能时,用grid包创建的图案可以正常填充普通非sf数据(如柱状图),但填充sf地理数据时触发报错。

可正常运行的代码(非sf数据)

library(tidyverse)
library(grid)
library(sf)
#> Linking to GEOS 3.11.0, GDAL 3.5.3, PROJ 9.1.0; sf_use_s2() is TRUE

checkered <- pattern(
  rectGrob(x = c(0.25, 0.75), y = c(0.25, 0.75), width = 0.5, height = 0.5),
  width = unit(5, "mm"), height = unit(5, "mm"), extend = "repeat",
  gp = gpar(fill = "limegreen")
)

# 非sf数据可正常运行
ggplot(mpg, aes(factor(cyl))) +
  geom_bar(fill = checkered)

非sf数据的图案填充效果

sf数据报错代码及信息

# sf数据无法运行
china <- spData::world |> filter(iso_a2 == "CN")

ggplot() + 
  geom_sf(data = china, fill = checkered)
#> Error in `geom_sf()`:
#> ! Problem while converting geom to grob.
#> ℹ Error occurred in the 1st layer.
#> Caused by error:
#> ! Unknown colour name: list(f = function () 
#> {
#>     grid.draw(gTree(children = gList(grob), gp = gp), recording = FALSE)
#> }, x = 0.5, y = 0.5, width = 5, height = 5, hjust = 0.5, vjust = 0.5, extend = "repeat", group = TRUE)

解决方案

geom_sf不支持直接将pattern()对象传入fill参数,需要通过映射填充变量 + 图案比例尺的方式实现:

library(tidyverse)
library(grid)
library(sf)
library(spData)

checkered <- pattern(
  rectGrob(x = c(0.25, 0.75), y = c(0.25, 0.75), width = 0.5, height = 0.5),
  width = unit(5, "mm"), height = unit(5, "mm"), extend = "repeat",
  gp = gpar(fill = "limegreen")
)

china <- world |> filter(iso_a2 == "CN")

ggplot() + 
  geom_sf(data = china, aes(fill = "pattern")) +
  scale_fill_pattern(values = checkered, guide = "none")

原理说明

通过将fill映射到一个固定字符串(这里用"pattern"),再用scale_fill_pattern()指定对应的图案值,就能让geom_sf正确识别并应用图案填充,避免直接传入pattern()对象导致的类型识别错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 06:03:34