如何将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数据无法运行 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
相关产品推荐
相关产品推荐

