R绘图|3分钟复现瑞士“苏黎世大学”Nature全球地图——基于R包ggplot2+sf等

一、引言

本文我们复现苏黎世大学团队François Keck等在Nature最新文章"The global human impact on biodiversity"中的全球地图。

之前的图纸是在平面坐标系里面进行绘制,本次我们在罗宾逊投影中进行绘制。整体代码逻辑非常简单,就是采样点坐标系的转换,地图坐标系转换图绘制(采用的sf包),ggplot绘制点图。

1.1 要复现的图纸

图源:Keck, F., Peller, T., Alther, R. et al. Nature (2025).

1.2本代码绘图结果

可以说一模一样,这个图纸基本完美复现原文图片!!

二、示例数据和R代码

2.1 准备数据

world_shp 文件夹,全球地图数据信息集,用于绘制地图

data.json 数据信息总结,用于绘图的有经纬度列Longitude和Latitude,和alpha_diversity(地图上的点)

⚠️根据自己的数据进行整理后绘图,有问题可以留言获取帮助

2.2 R代码

⚠️该代码适用于上述数据,要完成自己的任务适当调整! 创建一个地图,展示不同采样点的数据分布,特别是展示是否包含 alpha 多样性数据,并结合全球国界数据进行可视化。

2.2.1数据处理

**读取世界地图数据:**读取 Shapefile (TM_WORLD_BORDERS_SIMPL-0.3.shp) 以获取全球国界数据。

**处理缺失值:**删除包含缺失经纬度 (Longitude 和 Latitude) 的记录,保留有效数据。

空间数据转换:将数据从常规数据框转换为空间数据对象 (sf),设置坐标系统为 WGS84 (EPSG:4326)。将坐标数据转换为罗宾逊投影坐标系统,以便于地图可视化。

数据随机化和标记:创建新列 has_alpha,根据是否包含 alpha 多样性数据标记为 "Community composition only" 或 "Local diversity and community composition"。随机打乱数据顺序,以便更好地展示。

**关闭 S2 球面几何处理:**禁用 S2 几何处理,以避免某些空间计算错误。

空间数据处理:

1.将多边形转换为单个多边形要素。

2.计算每个多边形的面积,并过滤掉面积过小的区域(如小岛,面积 < 10⁹ 平方米)。

3.通过 st_buffer(0) 修复可能的几何错误。

4.裁剪到标准经纬度范围(经度 -180° 至 180°,纬度 -90° 至 90°)。

5.转换为罗宾逊投影,优化全球地图展示效果。

2.2.2. 绘制地图

基础地图绘制 (map)

使用 ggplot2 绘制世界地图底图 (geom_sf),填充颜色为灰色 (grey80)。

添加采样点 (map + geom_sf)

读取采样数据 (dat_rob),并按 has_alpha 变量进行着色:

蓝色 (#00364eff):仅包含群落组成数据。

青色 (#00b9ffff):包含局部多样性数据。

随机分组采样点,避免绘图时数据点过度重叠。

设定点的形状(shape = 20,实心圆点)和大小(size = 0.5)。

优化地图样式 (theme_minimal())

移除标题、坐标轴标签和边距,保持地图简洁清晰。

调整图例位置至底部,并优化图例的文本大小和间距。

2.2.3 最终输出

保存高分辨率图片 (ggsave)

以 800 DPI 高分辨率 将地图保存为 map.png,尺寸设定为 6×3 英寸,背景颜色为白色 (bg = "white")。

2.3 R包加载并加载数据

R 复制代码
#清理所有对象
rm(list=ls())

# 加载必要的库
library(dplyr)       # 数据操作和转换
library(ggplot2)     # 数据可视化
library(sf)          # 空间数据处理
library(forcats)     # 因子变量处理
library(rphylopic)   # 生物图标处理
library(scales)      # 图形比例尺调整
library(patchwork)   # 多图拼接

# 读取JSON数据并转换为tibble格式
dat <- jsonlite::read_json("data.json", simplifyVector = TRUE) %>% 
  as_tibble()

2.4 数据整理

R 复制代码
## 处理数据
dat_rob <- dat %>% 
  # 移除经纬度缺失的记录
  filter(!is.na(Longitude), !is.na(Latitude))

dat_rob1 <- dat_rob %>% 
  # 转换为sf对象(空间数据格式),指定经纬度列和坐标系(WGS84)
  sf::st_as_sf(coords = c("Longitude", "Latitude"), crs = 4326) %>% 
  # 转换到罗宾逊投影坐标系
  sf::st_transform(crs = sf::st_crs("+proj=robin +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs +type=crs")) 


dat_rob <- dat_rob1%>% 
  # 创建新列标记是否包含alpha多样性数据
  mutate(has_alpha = ifelse(is.na(alpha_diversity), "Community composition only", "Local diversity and community composition")) %>% 
  # 随机打乱数据顺序(prop=1表示全部数据)
  slice_sample(prop = 1)

# 关闭S2球面几何处理(避免某些空间计算错误)
sf::sf_use_s2(FALSE)

2.5 绘图

R 复制代码
## 创建地图
map <- sf::read_sf("World_shp/TM_WORLD_BORDERS_SIMPL-0.3.shp") %>% 
  # 将多边形转换为单个多边形要素
  sf::st_cast("POLYGON") %>% 
  # 计算每个多边形的面积
  mutate(area = sf::st_area(geometry)) %>% 
  # 过滤掉面积过小的多边形(小于10^9平方米)
  filter(as.numeric(area) > 10^9) %>% 
  # 修复可能的几何错误
  sf::st_buffer(0) %>% 
  # 裁剪到标准经纬度范围
  sf::st_crop(sf::st_bbox(c(xmin = -180, xmax = 180, ymin = -90, ymax = 90))) %>% 
  # 同样转换为罗宾逊投影
  sf::st_transform(crs = sf::st_crs("+proj=robin +lon_0=0 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs +type=crs")) 

map <- map %>%
  # 开始ggplot绘图
  ggplot() +
  # 绘制世界地图底图
  geom_sf(fill = "grey80", colour = "grey80") +
  # 添加采样点数据,按has_alpha分组着色
  geom_sf(aes(color = has_alpha, 
              group = cut(sample(seq(1, nrow(dat_rob))), 100)),  # 分组用于避免过度绘图
              shape = 20,       # 点形状(实心圆点)
              size = 0.5,       # 点大小
              data = dat_rob    # 使用的数据
    )    +
      # 设置颜色方案
      scale_color_manual(values = c("#00364eff", "#00b9ffff")) +
      # 设置x轴刻度(虽然地图投影后可能不直接使用)
      scale_x_continuous(breaks = seq(-180, 180, 45))+
      # 使用简约主题
      theme_minimal() +
      theme(
        plot.title = element_blank(),          # 无标题
        plot.margin = margin(t = 0, r = 0, b = 0, l = 0),  # 无边距
        legend.position = "bottom",            # 图例在底部
        legend.title = element_blank(),        # 无图例标题
        legend.text = element_text(size = 7),   # 图例文字大小
        legend.margin = margin(t = 0, r = 0, b = 0, l = 0), # 图例无边距
        legend.box.margin = margin(t = 0, r = 0, b = 0, l = 0), # 图例框无边距
        axis.text = element_blank(),           # 无坐标轴文字
        axis.title = element_blank()           # 无坐标轴标题
      )

# 显示地图
map

ggsave("map.png",plot=map,dpi=800,height =3,width=6,bg = "white")

2.6 输出结果

三、参考文献

1\] Keck, F., Peller, T., Alther, R. *et al.* The global human impact on biodiversity. *Nature* (2025). ## 四、相关信息 **!!!本文内容由小编总结互联网和文献内容总结整理,如若侵权,联系立即删除!** **!!!有需要的小伙伴评论区获取今天的测试代码和实例数据。** **📌示例代码中提供了数据和代码,小编已经测试,可直接运行。** **以上就是本节所有内容。** **如果这篇文章对您有用,请帮忙一键三连(点赞、收藏、评论、分享),让该文章帮助到更多的小伙伴。**

相关推荐
DonciSacer34 分钟前
第一章-Rust入门
开发语言·后端·rust
西京刀客1 小时前
golang常用库之-标准库text/template
开发语言·后端·golang
落榜程序员1 小时前
浅拷贝和深拷贝的区别
java·开发语言
purrrew2 小时前
【Java ee初阶】多线程(7)
java·开发语言
元亓亓亓2 小时前
Java后端开发day39--方法引用
java·开发语言
步行cgn3 小时前
GZIPOutputStream 类详解
java·开发语言·intellij-idea
HelloZheQ3 小时前
Java:从入门到精通,你的编程之旅
java·开发语言
Cyanto4 小时前
Java使用JDBC操作数据库
java·开发语言·数据库
zxctsclrjjjcph4 小时前
【动态规划】子序列问题
开发语言·c++·算法·动态规划·力扣