R语言绘制美国州地图:图片适配州形状方法及报错修复
R绘制美国分州球队收藏卡销量地图问题修复方案
问题梳理
- 实现目标:基于体育球队收藏卡分州销量数据,调用
USAboundaries、sf、tidyverse、rasterpic、tidyterra、ggplot2等R包,绘制美国本土州地图,将各州销量最高的球队logo填充至对应州轮廓内,实现logo完全贴合州边界的可视化效果 - 现有基础:已完成基础代码框架,导入了州与对应热销球队的January销量数据集、球队logo URL映射表,尝试通过
rasterpic_img、geom_spatraster_rgb函数循环填充logo - 运行异常:
- 初步输出的logo尺寸过大,溢出对应州轮廓范围,未适配州形状
- 循环执行时触发固定报错:
Error: $ Operator is invalid for atomic vectors
异常原因排查
1. 美元操作符报错原因
该报错本质是对原子型向量(普通数值/字符向量、非结构化的坐标矩阵、被意外转换格式的sf/栅格对象)使用了$做子集提取,常见触发场景:
- 循环索引写法错误,比如直接写
for(i in nrow(数据集)),i只是单个数值不是遍历序列,取子集时把整列数据拉成了原子向量,后续调用$取字段直接报错 - 提取单州边界时没有保留sf对象格式,提前把几何列拆成了普通坐标向量传入
rasterpic_img,后续对返回值用$取属性时触发报错 - 对生成的S4格式栅格对象错误使用
$提取内部图层,原子向量结构不支持该操作
2. logo溢出边界原因
核心是生成logo栅格时没有做对齐、裁切、掩膜处理:
rasterpic_img默认保持logo原始宽高比,不会自动适配州边界的范围,也不会自动裁掉超出轮廓的部分- 没有传入州边界的空间范围作为生成基准,logo用原始像素尺寸输出,自然会溢出边界
- 未做掩膜处理,即使范围对齐,州轮廓外的logo部分也不会透明隐藏
可直接运行的修复代码
# 加载依赖包 library(USAboundaries) library(sf) library(tidyverse) library(rasterpic) library(tidyterra) library(ggplot2) # 1. 预处理美国本土州边界 us_states <- us_states(resolution = "low") %>% # 剔除阿拉斯加、夏威夷和海外领地,保留本土48州 filter(!state_abbr %in% c("AK", "HI", "PR", "GU", "VI", "AS", "MP")) %>% # 转换为北美等面积投影,避免形状拉伸变形 st_transform(5070) # 2. 关联销量数据和logo映射表(替换为你实际的数据集对象名) # jan_sales 需包含state_abbr(州缩写)、top_team(销量最高球队名)字段 # logo_map 需包含top_team(球队名)、logo_url(logo对应链接)字段 plot_base <- us_states %>% left_join(jan_sales, by = "state_abbr") %>% left_join(logo_map, by = "top_team") # 3. 循环生成适配州边界的logo栅格 state_logo_list <- list() # 固定用1:nrow做遍历序列,避免索引变成单值触发格式错误 for (i in 1:nrow(plot_base)) { # 提取单州数据,全程保持sf对象格式,不提前拆解几何列 single_state <- plot_base[i, ] # 生成贴合边界的logo栅格 state_logo <- rasterpic_img( x = single_state, img = single_state$logo_url, crop = T, # 自动裁切到单州的边界范围 mask = T, # 直接用州轮廓做掩膜,超出边界的部分自动透明 asp = 1, # 宽高比适配,可根据实际显示效果微调0.9-1.1区间 expand = 0 # 关闭默认范围扩展,刚好贴合边界不溢出 ) state_logo_list[[i]] <- state_logo } # 4. 组合绘图 final_plot <- ggplot() + # 批量添加各州logo栅格,不对栅格对象用$操作 lapply(state_logo_list, function(rast_obj) { geom_spatraster_rgb(data = rast_obj, max_col_value = 255) }) + # 添加白色州界描边,提升辨识度 geom_sf(data = us_states, fill = NA, color = "white", linewidth = 0.6) + # 清空多余背景和坐标轴 theme_void() # 导出结果 ggsave("分州球队热销卡地图.png", final_plot, width = 12, height = 7, dpi = 300)
关键修复点说明
- 针对美元操作符报错:
- 循环索引统一用
1:nrow(数据框)写法,避免索引为单值导致取子集格式异常 - 空间数据全程保留sf/SpatRaster的结构化格式,不提前拆解为普通向量
- 栅格对象直接传入绘图函数,不对S4结构的栅格用
$取子集
- 循环索引统一用
- 针对logo溢出问题:
- 生成栅格时直接传入单州sf对象作为空间基准,自动对齐坐标范围
- 开启
crop和mask参数,从范围裁切、轮廓掩膜两层保证logo不超出州界 - 设置
expand=0关闭默认的范围外扩,提前转等面积投影避免变形错位
内容的提问来源于stack exchange,提问作者user14452102
相关产品推荐
相关产品推荐

