告别地图绘制难题:用r-spatial/sf和ggplot2轻松实现专业空间数据可视化
【免费下载链接】sf Simple Features for R 项目地址: https://gitcode.com/gh_mirrors/sf/sf
在数据分析领域,空间数据可视化是揭示地理模式和空间关系的关键手段。然而,许多R语言用户仍在为繁琐的地图绘制流程、不兼容的数据格式和难以定制的可视化效果而困扰。本文将系统介绍如何利用r-spatial/sf(Simple Features for R)包和ggplot2绘制高质量空间数据可视化地图,从数据准备到高级定制,一站式解决空间可视化难题。
核心工具与项目概述
r-spatial/sf是R语言中处理简单要素(Simple Features)空间数据的核心包,遵循开放地理空间联盟(OGC)标准,提供了强大的空间数据读写、操作和分析功能。ggplot2则是R语言最流行的数据可视化包,通过图层语法实现灵活的图形定制。
项目基础文件结构:
- 核心空间可视化代码:R/plot.R
- ggplot2示例脚本:demo/ggplot.R
- 示例数据集:inst/gpkg/nc.gpkg
sf包的plot函数支持多种几何类型的可视化,包括点(POINT)、线(LINESTRING)、面(POLYGON)等,通过R/plot.R中的plot.sfc_POINT、plot.sfc_LINESTRING和plot.sfc_POLYGON等方法实现不同几何对象的绘制逻辑。
环境准备与数据加载
安装与加载必要包
开始前需要安装并加载sf和ggplot2包,以及用于数据处理的dplyr和tidyr:
# 安装必要的R包
install.packages(c("sf", "ggplot2", "dplyr", "tidyr"))
# 加载包
library(sf) # 处理空间数据
library(ggplot2) # 数据可视化
library(dplyr) # 数据处理
library(tidyr) # 数据重塑
加载示例空间数据
sf包内置了北卡罗来纳州(North Carolina)的 counties 数据集,包含人口、收入和犯罪率等属性数据:
# 从sf包中读取内置的北卡罗来纳州空间数据集
nc <- st_read(system.file("gpkg/nc.gpkg", package = "sf"), quiet = TRUE)
# 查看数据结构
print(class(nc)) # "sf" "data.frame" - 空间数据框
print(head(names(nc)))# 查看属性列名
print(st_crs(nc)) # 查看坐标参考系 (CRS: EPSG:4267 - NAD83)
数据集包含以下关键信息:
- 几何列(geometry):多边形要素,表示北卡罗来纳州各郡的边界
- 属性列:包括SID74(1974年犯罪率)、SID79(1979年犯罪率)、NAME(郡名)等
基础空间可视化:sf内置plot函数
sf包提供了便捷的内置plot方法,可以快速可视化空间数据。这种方法适合快速探索数据,但定制化程度有限。
单属性地图
使用plot()函数直接可视化sf对象的单个属性:
# 绘制1979年犯罪率(SID79)的专题地图
plot(nc["SID79"],
main = "1979年北卡罗来纳州各郡犯罪率", # 标题
key.pos = 4, # 图例位置(4=右侧)
pal = sf.colors(10), # 颜色方案
border = "white") # 多边形边界颜色
多属性对比
同时可视化多个属性,实现快速对比分析:
# 对比1974年和1979年的犯罪率
plot(nc[c("SID74", "SID79")],
main = c("1974年犯罪率", "1979年犯罪率"), # 子图标题
nbreaks = 5, # 颜色分级数量
pal = heat.colors, # 使用热力图颜色
key.width = lcm(1.5), # 图例宽度
key.length = lcm(8)) # 图例长度
sf内置plot函数的核心参数通过R/plot.R定义,包括:
key.pos:控制图例位置(1=下,2=左,3=上,4=右)pal:颜色映射函数,默认使用sf.colors()nbreaks:数值属性的分级数量border:多边形边界颜色
ggplot2空间可视化:灵活定制的高级方案
ggplot2通过geom_sf()几何对象实现与sf包的无缝集成,支持图层化构建复杂地图,是创建 publication 级别可视化的首选方案。
基础sf图层
使用ggplot2绘制基础空间图层,结合aes()映射属性到视觉特征:
# 基础地图:填充色映射1979年犯罪率
ggplot(nc) +
geom_sf(aes(fill = SID79)) + # sf图层,填充色映射SID79
ggtitle("北卡罗来纳州各郡1979年犯罪率分布") +
theme_minimal()
多图层叠加
组合多个地理图层,添加标注和参考线:
# 高级地图:多图层叠加
ggplot() +
# 底图:郡边界填充
geom_sf(data = nc, aes(fill = SID79), alpha = 0.8) +
# 叠加:郡边界线
geom_sf(data = nc, fill = NA, color = "black", size = 0.3) +
# 添加郡名标签(仅显示人口较多的郡)
geom_sf_text(data = filter(nc, BIR79 > 15000),
aes(label = NAME), size = 3) +
# 颜色方案与标题
scale_fill_viridis_c(option = "plasma", name = "犯罪率") +
ggtitle("北卡罗来纳州高人口郡犯罪率与位置分布",
subtitle = "1979年数据,仅显示人口>15,000的郡") +
theme_bw() +
theme(plot.title = element_text(hjust = 0.5),
plot.subtitle = element_text(hjust = 0.5))
分面对比可视化
使用分面(facet)功能对比不同年份的犯罪率变化,代码来自demo/ggplot.R:
# 数据重塑:宽格式转长格式,便于分面
nc_long <- nc %>%
select(SID74, SID79, NAME, geometry) %>% # 选择需要的列
pivot_longer(cols = starts_with("SID"), # 重塑SID74和SID79列
names_to = "Year",
values_to = "CrimeRate") %>%
mutate(Year = ifelse(Year == "SID74", "1974年", "1979年")) # 重命名年份
# 分面地图:对比两年犯罪率
ggplot(nc_long) +
geom_sf(aes(fill = CrimeRate)) +
facet_wrap(~Year) + # 按年份分面
scale_fill_gradient(low = "white", high = "darkred", name = "犯罪率") +
ggtitle("北卡罗来纳州犯罪率时空变化对比") +
theme_void() + # 无背景主题
theme(legend.position = "bottom")
坐标参考系与地图投影
空间数据可视化的关键在于选择合适的坐标参考系(CRS)和地图投影。sf包提供了强大的坐标转换功能。
查看与转换CRS
# 查看原始CRS
print(st_crs(nc)) # EPSG:4267 (NAD83) - 地理坐标系
# 转换为UTM投影坐标系(适合距离测量)
nc_utm <- st_transform(nc, crs = 32617) # EPSG:32617 - UTM 17N
print(st_crs(nc_utm))
# 转换为阿尔伯斯等积投影(适合美国区域地图)
nc_albers <- st_transform(nc, crs = "+proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=37.5 +lon_0=-96")
不同投影效果对比
# 创建三个不同投影的地图
p1 <- ggplot(nc) + geom_sf() + ggtitle("原始地理坐标系 (WGS84)")
p2 <- ggplot(nc_utm) + geom_sf() + ggtitle("UTM投影 (等角圆柱投影)")
p3 <- ggplot(nc_albers) + geom_sf() + ggtitle("阿尔伯斯等积投影")
# 组合显示
library(patchwork)
p1 + p2 + p3 + plot_layout(ncol = 1)
不同投影适用于不同场景:
- 地理坐标系(WGS84/EPSG:4326):适合全球尺度,距离和面积会有畸变
- UTM投影:适合局部区域,保持距离和方向准确性
- 阿尔伯斯等积投影:适合中纬度地区,保持面积比例
高级定制与美化
ggplot2的强大之处在于其高度可定制性,通过调整主题、颜色比例尺和标注等元素,可以创建专业级可视化作品。
自定义颜色方案
选择合适的颜色方案对空间可视化至关重要,应考虑数据类型(分类/连续)和受众:
# 连续数据:使用viridis色系(色盲友好)
ggplot(nc) +
geom_sf(aes(fill = SID79)) +
scale_fill_viridis_c(option = "magma", # 可选: "viridis", "plasma", "inferno", "magma"
breaks = c(0, 50, 100, 150),
labels = c("0", "50", "100", "150+")) +
labs(fill = "犯罪率\n(每10万人)",
title = "北卡罗来纳州犯罪率分布",
caption = "数据来源: r-spatial/sf内置nc数据集") +
theme_minimal()
# 分类数据:使用hue色系
nc$REGION <- cut(nc$AREA, breaks = 3, labels = c("小面积", "中面积", "大面积"))
ggplot(nc) +
geom_sf(aes(fill = REGION), color = "white") +
scale_fill_brewer(palette = "Set1", name = "面积分类") +
theme_bw()
添加背景地图
结合ggspatial包添加底图,增强地图上下文:
# 安装并加载ggspatial
install.packages("ggspatial")
library(ggspatial)
# 添加底图
ggplot(nc) +
annotation_map_tile(
type = "osm", # 底图类型
zoom = 7 # 缩放级别
) +
geom_sf(aes(fill = SID79), alpha = 0.6, color = NA) + # 半透明填充
scale_fill_viridis_c(option = "cividis") +
ggspatial::annotation_scale(location = "bl") + # 添加比例尺
ggspatial::annotation_north_arrow( # 添加指北针
location = "tr", which_north = "true",
style = north_arrow_fancy_orienteering
) +
theme_void()
地图主题定制
通过theme()函数定制地图元素,创建符合发表要求的可视化作品:
ggplot(nc) +
geom_sf(aes(fill = SID79), color = "black", size = 0.2) +
scale_fill_gradient(low = "white", high = "#C41E3A", name = "犯罪率") +
ggtitle("1979年北卡罗来纳州各郡犯罪率空间分布") +
theme(
plot.title = element_text(size = 16, hjust = 0.5, face = "bold"),
legend.position = "right",
legend.key.height = unit(2, "cm"),
panel.background = element_rect(fill = "#F5F5F5"), # 浅灰色背景
panel.grid = element_line(color = "white", size = 0.3) # 白色网格线
) +
guides(fill = guide_colorbar(title.position = "top", title.hjust = 0.5))
实战案例:犯罪率变化与人口相关性分析
综合运用sf和ggplot2进行空间数据分析,探索1974-1979年犯罪率变化与人口增长的关系。
数据预处理
# 计算犯罪率变化和人口增长率
nc_analysis <- nc %>%
mutate(
CrimeChange = SID79 - SID74, # 犯罪率变化
CrimeChangePerc = (SID79/SID74 - 1)*100, # 犯罪率变化百分比
PopGrowth = (BIR79 - BIR74)/BIR74*100 # 人口增长率
) %>%
filter(!is.na(CrimeChangePerc), !is.na(PopGrowth)) # 去除缺失值
空间模式探索
# 犯罪率变化空间分布
p_change <- ggplot(nc_analysis) +
geom_sf(aes(fill = CrimeChangePerc)) +
scale_fill_gradient2(
low = "blue", mid = "white", high = "red",
midpoint = 0, name = "犯罪率变化\n(%)"
) +
ggtitle("1974-1979年犯罪率变化百分比") +
theme_minimal()
# 犯罪率变化与人口增长相关性
p_cor <- ggplot(nc_analysis, aes(x = PopGrowth, y = CrimeChangePerc)) +
geom_point(size = 2, alpha = 0.7) +
geom_smooth(method = "lm", color = "red", se = FALSE) +
labs(x = "人口增长率 (%)", y = "犯罪率变化 (%)",
title = "犯罪率变化与人口增长相关性") +
theme_minimal()
# 组合图表
p_change + p_cor + plot_layout(widths = c(2, 1))
高值区域分析
识别犯罪率高值区域(热点)并进行标注:
# 识别犯罪率最高的5个郡
top_crime <- nc_analysis %>%
arrange(desc(SID79)) %>%
slice(1:5)
ggplot(nc_analysis) +
geom_sf(aes(fill = SID79), color = NA) +
geom_sf(data = top_crime, color = "yellow", fill = NA, size = 1.2) + # 高亮边界
geom_sf_text(data = top_crime, aes(label = NAME), color = "yellow", size = 3) + # 标注名称
scale_fill_viridis_c(option = "plasma") +
ggtitle("北卡罗来纳州犯罪率最高的5个郡",
subtitle = "1979年数据") +
theme_minimal()
总结与进阶学习
本文详细介绍了使用r-spatial/sf和ggplot2进行空间数据可视化的完整流程,从基础操作到高级定制,涵盖了空间数据处理的核心技能。通过掌握这些工具,您可以轻松创建专业级空间可视化作品,揭示数据中的地理模式和空间关系。
核心知识点回顾
- sf包:提供空间数据读写、转换和操作能力,是R语言空间分析的基础
- ggplot2:通过
geom_sf()实现空间数据可视化,支持图层化构建复杂地图 - 坐标参考系:根据研究区域和需求选择合适的CRS,理解地理坐标系与投影坐标系的区别
- 可视化设计:合理选择颜色方案、分面方式和地图元素,创建信息丰富且美观的地图
进阶学习资源
- sf包官方文档:R/plot.R提供了sf可视化函数的完整实现
- ggplot2空间可视化扩展:ggspatial、ggsn、cartogram等包
- 高级空间分析:spdep包(空间自相关)、raster包(栅格数据处理)
- 交互式地图:leaflet、mapview包实现交互式Web地图
通过结合sf的空间数据处理能力和ggplot2的可视化优势,您可以应对从简单探索性分析到复杂空间模式研究的各种需求,为数据分析增添强大的空间维度。
【免费下载链接】sf Simple Features for R 项目地址: https://gitcode.com/gh_mirrors/sf/sf
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



