如何让ggrough生成的sf choropleth地图显示图例框
解决ggrough连续配色图例框缺失问题
问题场景
使用ggplot2+sf创建北卡罗来纳州连续配色 choropleth 地图时,图例显示正常;但通过ggrough转换为手绘风格后,连续配色的图例颜色框消失,仅保留文字,而离散配色的图例可正常显示。
原始正常地图代码:
library(ggplot2) library(sf) nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE) b <- ggplot(nc) + geom_sf(aes(fill = AREA)) b
ggrough转换代码(原版本存在图例问题):
#devtools::install_github("xvrdm/ggrough") library(ggrough) library(magrittr) # 原自定义parse_rough函数 function (svg, geom) { rough_els <- list() if (geom %in% c("GeomCol", "GeomBar", "GeomTile", "Background")) { rough_els <- append(rough_els, parse_rects(svg)) } if (geom %in% c("GeomArea", "GeomViolin", "GeomSmooth", "Background")) { rough_els <- append(rough_els, parse_areas(svg)) } if (geom %in% c("GeomPoint", "GeomJitter", "GeomDotPlot", "Background")) { rough_els <- append(rough_els, parse_circles(svg)) } if (geom %in% c("GeomLine", "GeomSmooth", "Background")) { rough_els <- append(rough_els, parse_lines(svg)) } if (geom %in% c("Background")) { rough_els <- append(rough_els, parse_texts(svg)) } if (geom %in% c("GeomSf")) { rough_els <- append(rough_els, parse_sf(svg)) } purrr::map(rough_els, ~purrr::list_modify(.x, geom = geom)) } parse_sf <- function (svg) { shape <- "path" keys <- NULL ggrough:::parse_shape(svg, shape, keys) %>% { purrr::map(., ~purrr::list_modify(.x, points = .x$d, shape = "path" )) } } nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE) b <- ggplot(nc) + geom_sf(aes(fill = AREA)) b options <- list(GeomSf=list(fill_style="hachure", angle_noise=0.5, gap_noise=0.2, gap=1.5, fill_weight=1)) get_rough_chart(b, options)
解决方案
问题根源是连续配色图例的颜色框属于SVG的Background范畴下的rect元素,但原自定义parse_rough函数仅处理了Background中的文本,未对矩形进行解析;而离散配色的图例色块属于GeomTile,已被原代码覆盖处理。
修改parse_rough函数,确保Background范畴的矩形元素被解析,同时可额外配置图例框的手绘风格:
修改后的完整代码
#devtools::install_github("xvrdm/ggrough") library(ggrough) library(magrittr) library(purrr) # 修改后的parse_rough函数:保留Background的rect解析逻辑 parse_rough <- function (svg, geom) { rough_els <- list() if (geom %in% c("GeomCol", "GeomBar", "GeomTile", "Background")) { # Background包含在内,解析图例矩形 rough_els <- append(rough_els, parse_rects(svg)) } if (geom %in% c("GeomArea", "GeomViolin", "GeomSmooth", "Background")) { rough_els <- append(rough_els, parse_areas(svg)) } if (geom %in% c("GeomPoint", "GeomJitter", "GeomDotPlot", "Background")) { rough_els <- append(rough_els, parse_circles(svg)) } if (geom %in% c("GeomLine", "GeomSmooth", "Background")) { rough_els <- append(rough_els, parse_lines(svg)) } if (geom %in% c("Background")) { rough_els <- append(rough_els, parse_texts(svg)) } if (geom %in% c("GeomSf")) { rough_els <- append(rough_els, parse_sf(svg)) } purrr::map(rough_els, ~purrr::list_modify(.x, geom = geom)) } parse_sf <- function (svg) { shape <- "path" keys <- NULL ggrough:::parse_shape(svg, shape, keys) %>% { purrr::map(., ~purrr::list_modify(.x, points = .x$d, shape = "path" )) } } # 生成地图并转换为手绘风格 nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE) b <- ggplot(nc) + geom_sf(aes(fill = AREA)) options <- list(GeomSf=list(fill_style="hachure", angle_noise=0.5, gap_noise=0.2, gap=1.5, fill_weight=1), # 可选:为图例框配置统一的手绘风格 Background=list(fill_style="hachure", fill_weight=1)) get_rough_chart(b, options)
关键说明
- 确保
Background被包含在parse_rects的判断条件中,这样连续图例的颜色条rect会被解析为手绘风格元素。 - 可选添加
Background的风格配置,让图例框与地图的手绘风格保持一致。
运行修改后的代码后,连续配色的图例颜色框会以手绘风格正常显示。
内容的提问来源于stack exchange,提问作者bill999
相关产品推荐
相关产品推荐

