首先找到地图数据, 导入 R, 然后绘制地图.

32.1 PKG

Show/Hide Code
library(leaflet)    # 创建交互式地图
library(ggmap)      # 绘制静态地图(Google/Stadia)
library(gridExtra)  # 排列多个图表
library(maps)       # 提供基础世界/国家地图数据
library(mapdata)    # 提供额外的地图数据(如中国,日本)
library(oz)         # 绘制澳大利亚地图
library(sf)         # 处理空间数据(Shapefiles/GeoJSON)
library(ggiraph)    # 创建交互式ggplot图表
library(ggplot2)    # 数据可视化
library(dplyr)      # 数据处理
library(patchwork)  # 组合图表
library(tidyr)      # 数据整理
library(knitr)      # 在报告中渲染表格
library(rmapshaper) # 简化地理空间对象
library(rayshader)  # 2D/3D地形可视化
library(raster)     # 栅格数据处理
library(geodata)    # 地理数据获取

32.2 动态

leaflet 是 R 语言中一个非常强大的地图包, 可以绘制静态和动态地图.

32.2.1 基本

Show/Hide Code
# 加载leaflet库
library(leaflet)

m <- leaflet() |> # 初始化leaflet地图对象
  addTiles()      # 添加默认地图瓦片

m

基础OpenStreetMap交互地图

32.2.2 区域

要指定要显示的地图区域,只需在 setView() 调用中指定纬度、经度以及缩放级别:

- 经度 `lng`
- 纬度 `lat`
- 缩放级别 `zoom`
Show/Hide Code
# 加载leaflet库
library(leaflet)

# 创建地图并设置视图
m <- leaflet() |>                                    # 初始化leaflet地图对象
  addTiles() |>                                      # 添加默认OpenStreetMap地图瓦片
  setView(lng = 166.45, lat = -22.25, zoom = 8)      # 设置地图中心点和缩放级别

# 显示地图
m

设置特定视图的交互地图

32.2.3 添加圆形

Show/Hide Code
# 加载leaflet库
library(leaflet)

# 创建20个随机标记点的数据
data = data.frame(
  long = sample(seq(-150, 150), 20),                  # 生成20个随机经度值
  lat = sample(seq(-50, 50), 20),                     # 生成20个随机纬度值
  val = round(rnorm(20), 2),                          # 生成20个随机数值
  name = paste("point", letters[1:20], sep = "_")     # 创建点位名称
)

# 创建地图并在每个位置显示圆形标记
m = leaflet(data = data) |>                          # 使用数据初始化leaflet地图
  addTiles() |>                                      # 添加默认地图瓦片
  addCircleMarkers(~long, ~lat, popup = ~as.character(name))  # 添加圆形标记和弹出信息

# 显示地图
m

带有圆形标记的随机点位地图

还可以自定义圆形:

Show/Hide Code
# 创建20个随机标记点的数据
data = data.frame(
  long = sample(seq(-150, 150), 20),                  # 生成20个随机经度值
  lat = sample(seq(-50, 50), 20),                     # 生成20个随机纬度值
  val = round(rnorm(20), 2),                          # 生成20个随机数值
  name = paste("point", letters[1:20], sep = "_")     # 创建点位名称
)

# 创建带有自定义圆形标记的地图
# 圆圈大小以像素为单位定义,缩放时大小不会改变
m = leaflet(data = data) |>                          # 使用数据初始化leaflet地图
  addTiles() |>                                      # 添加默认地图瓦片
  addCircleMarkers(
    ~long, ~lat,                                     # 设置经纬度坐标
    radius = ~val * 14,                              # 圆圈半径根据val值调整
    color = ~ifelse(data$val > 0, "red", "orange"),  # 根据val值设置颜色
    stroke = TRUE,                                   # 显示边框
    fillOpacity = 0.2,                               # 设置填充透明度
    popup = ~as.character(name)                      # 添加弹出信息
  )

# 显示地图
m

自定义圆形标记的随机点位地图

Show/Hide Code
# 加载leaflet库
library(leaflet)

# 创建20个随机标记点的数据
data = data.frame(
  long = sample(seq(-150, 150), 20),                  # 生成20个随机经度值
  lat = sample(seq(-50, 50), 20),                     # 生成20个随机纬度值
  val = round(rnorm(20), 2),                          # 生成20个随机数值
  name = paste("point", letters[1:20], sep = "_")     # 创建点位名称
)

# 创建带有自定义圆形的地图
# 圆形半径以米为单位定义,缩放时大小会相应变化
m = leaflet(data = data) |>                          # 使用数据初始化leaflet地图
  addTiles() |>                                      # 添加默认地图瓦片
  addCircles(
    ~long, ~lat,                                     # 设置经纬度坐标
    radius = ~val * 1000000,                         # 圆形半径以米为单位,根据val值调整
    color = ~ifelse(data$val > 0, "red", "orange"),  # 根据val值设置颜色
    stroke = TRUE,                                   # 显示边框
    fillOpacity = 0.2,                               # 设置填充透明度
    popup = ~as.character(name)                      # 添加弹出信息
  ) |>
  setView(lng = 166.45, lat = 21, zoom = 2)          # 设置地图视图中心点和缩放级别

# 显示地图
m

可自定义大小的圆形标记,随缩放而变化

32.2.4 添加矩形

Show/Hide Code
# 加载leaflet库
library(leaflet)

# 创建20个随机标记点的数据
data = data.frame(
  long = sample(seq(-150, 150), 20),                  # 生成20个随机经度值
  lat = sample(seq(-50, 50), 20),                     # 生成20个随机纬度值
  val = round(rnorm(20), 2),                          # 生成20个随机数值
  name = paste("point", letters[1:20], sep = "_")     # 创建点位名称
)

# 创建带有矩形区域的地图
m = leaflet() |>                                     # 初始化leaflet地图对象
  addTiles() |>                                      # 添加默认地图瓦片
  addRectangles(
    lng1 = -118.456554, lat1 = 34.078039,            # 矩形第一个对角坐标
    lng2 = -118.436383, lat2 = 34.062717,            # 矩形第二个对角坐标
    fillColor = "transparent"                         # 设置填充颜色为透明
  )

# 显示地图
m   

在地图上添加矩形区域

32.2.5 地图类型

  • Nasa(夜光图): NASAGIBS.ViirsEarthAtNight2012
  • Google map(卫星图): Esri.WorldImagery
  • Gray(灰色): Esri.WorldGrayCanvas
  • Terrain(地形图): Esri.WorldTerrain
  • Topo Map(等高线图): Esri.WorldTopoMap
Show/Hide Code
library(leaflet)

# 背景地图 1:NASA 夜间灯光图
m <- leaflet() |>
  addTiles() |>                                           # 添加默认瓦片图层
  setView(lng = 2.34, lat = 48.85, zoom = 3)         # 设置地图中心和缩放级别
m |>
  addProviderTiles("NASAGIBS.ViirsEarthAtNight2012")    # 添加 NASA 2012 年夜间灯光底图
# 背景地图 2:世界影像图
m |>
  addProviderTiles("Esri.WorldImagery")                  # 添加 Esri 世界影像底图
# 背景地图 3:灰色底图
m |>
  addProviderTiles("Esri.WorldGrayCanvas")               # 添加 Esri 灰色底图
# 背景地图 4:地形图
m |>
  addProviderTiles("Esri.WorldTerrain")                  # 添加 Esri 地形底图
# 背景地图 5:等高线图
m |>
  addProviderTiles("Esri.WorldTopoMap")                  # 添加 Esri 等高线底图

NASA 夜间灯光图

世界影像图

灰色底图

地形图

等高线图

使用不同底图的交互式地图展示

32.3 静态

ggmap 包含生成静态地图的功能。本文将介绍其基本使用方法,即构建背景地图。其他函数可用于在地图上添加数据,例如气泡图或分级统计图。

32.3.1 Google

Google 现在需要 API 密钥; 见 ggmap::register_google()

Show/Hide Code
library(ggmap)

# 对于谷歌地图,需要指定查看窗口的中心位置
# 地图类型参数可选项:terrain / satellite / roadmap / hybrid

# 获取地图信息
map <- get_googlemap("Montpellier, France", zoom = 8, maptype = "terrain")

# 绘制地图
ggmap(map) +
  theme_void() +                                              # 使用空白主题
  ggtitle("terrain") +                                        # 添加标题
  theme(
    plot.title = element_text(colour = "orange"),             # 设置标题颜色为橙色
    panel.border = element_rect(colour = "grey", fill = NA, size = 2)  # 设置边框为灰色
  )

32.3.2 Stadia

需要注册 API 密钥; 见 ggmap::register_stadiamaps()

Show/Hide Code
# 加载库
library(ggmap)
library(gridExtra)

# 对于 Stamen 地图,需要指定查看窗口的边界
# 这是一个使用水彩背景的示例(澳大利亚周边地区)
map <- get_stadiamap(
  bbox = c(left = 110, bottom = -40, right = 160, top = -10),  # 设置地图边界
  zoom = 4,                                                      # 缩放级别
  maptype = "stamen_watercolor"                                         # 水彩风格
)

ggmap(map) +
  theme_void() +                                                 # 使用空白主题
  theme(
    plot.title = element_text(colour = "orange"),                # 设置标题颜色为橙色
    panel.border = element_rect(colour = "grey", fill = NA, size = 2)  # 设置边框为灰色
  )
Show/Hide Code
# 加载库
library(ggmap)
library(gridExtra)

# 让我们查看 Stamen 地图提供的所有可能性
maptype <- c(
  "terrain-labels", "terrain-lines", "toner", "toner-2011",
  "toner-background", "toner-hybrid", "toner-lines",
  "toner-lite", "watercolor"
)

mylist <- vector("list", length(maptype))                       # 创建列表存储地图

# 循环遍历所有地图类型
num <- 0
for (i in maptype) {
  num <- num + 1
  map <- get_stamenmap(
    bbox = c(left = 150, bottom = -30, right = 160, top = -25),  # 设置地图边界(澳大利亚东部)
    zoom = 8,                                                      # 缩放级别
    maptype = i                                                    # 当前地图类型
  )
  p <- ggmap(map) +
    theme_void() +                                                 # 使用空白主题
    ggtitle(i) +                                                   # 以地图类型作为标题
    theme(
      plot.title = element_text(colour = "orange"),                # 设置标题颜色为橙色
      panel.border = element_rect(colour = "grey", fill = NA, size = 2)  # 设置边框为灰色
    )
  mylist[[num]] <- p                                               # 将地图存入列表
}

# 使用 gridExtra 将所有地图排列在同一张图像中
n <- length(mylist)
nCol <- floor(sqrt(n))                                             # 计算列数
do.call("grid.arrange", c(mylist, ncol = nCol))                   # 排列所有地图

32.4 地图库

一些库提供了最常见的空间对象, 这避免了在网络上寻找信息的麻烦

  • Map 库:加拿大、法国、意大利、美国及其地区、世界城市、新西兰。
  • Mapdata 库(中国、日本、新西兰、高分辨率的全球地图)。
  • oz 库(澳大利亚)。

32.4.1 maps

包括: - World: world, world.cities, lakes - US: states, county, state, usa - France: france - Italy: italy - New zealand: nz

Show/Hide Code
library(maps)

# 查看所有可用空间对象
# help(package='maps')

# 绘制世界地图
map(
  'world',                    # 地图类型:世界地图
  col = "grey",              # 填充颜色:灰色
  fill = TRUE,               # 是否填充:是
  bg = "white",              # 背景颜色:白色
  lwd = 0.05,                # 边界线宽度:0.05
  mar = rep(0, 4),           # 图形边距:上下左右均为 0
  border = 0,                # 边框宽度:0(无边框)
  ylim = c(-80, 80)          # Y 轴范围:纬度 -80 到 80 度
)

使用 maps 包绘制的世界地图

32.4.2 mapdata

- china - 中国地图
- japan - 日本地图
- 其他世界地图版本,如太平洋中心版 (world2Hires)
- 使用 help(package='mapdata') 查看完整列表
Show/Hide Code
# 加载库
library(mapdata)

# 查看所有可用的地理空间对象:
# help(package='mapdata')

# 绘制日本地图:
map(
  'japan',              # 地图类型:中国
  col = "black",        # 边界颜色:黑色
  lwd = 1,              # 线条宽度:1
  mar = rep(0, 4)       # 图形边距:上下左右均为 0
)

使用 mapdata 包绘制日本地图

32.4.3 oz

使用 oz() 函数绘制国家概况,或使用 nsw()qld() 等绘制州。

输入 help(package='oz') 获取文档说明。

Show/Hide Code
# 加载oz包用于绘制澳大利亚地图
library(oz)

# 查看所有可用的地理空间对象:
# help(package='oz')

# 绘制澳大利亚地图
par(mar = rep(0, 4))              # 设置图形边距为0
oz(states = TRUE, col = "#69b3a2") # 绘制带州界的澳大利亚地图,使用绿色填充

澳大利亚地图

32.5 地图文件

还可以从网上找到地图数据, shape 文件或 geojson 文件, 然后使用 sf 包读取.

32.6 ggiraph

Show/Hide Code
# 加载必需的包
library(ggiraph)      # 交互式图表
library(ggplot2)      # 数据可视化
library(dplyr)        # 数据处理
library(patchwork)    # 图表拼接
library(tidyr)        # 数据整理
library(sf)           # 空间数据处理

# 设置随机种子以确保结果可重现
set.seed(123)

# 加载mtcars数据集并添加车型名称列
data(mtcars)
mtcars$car <- rownames(mtcars)

# 创建交互式散点图:重量 vs 油耗
p1 <- ggplot(mtcars, aes(wt, mpg, tooltip = car, data_id = car)) +
  geom_point_interactive(size = 4)

# 创建交互式柱状图:按油耗排序的车型
p2 <- ggplot(mtcars, aes(x = reorder(car, mpg), y = mpg, tooltip = car, data_id = car)) +
  geom_col_interactive() +
  coord_flip()

# 使用patchwork包组合两个图表
combined_plot <- p1 + p2 + plot_layout(ncol = 2)

# 创建交互式图表对象
interactive_plot <- girafe(ggobj = combined_plot)

# 显示交互式图表
interactive_plot

基于mtcars数据的交互式散点图和柱状图组合

Show/Hide Code
# 读取完整的世界地图数据
world_sf <- read_sf("https://raw.githubusercontent.com/holtzy/R-graph-gallery/master/DATA/world.geojson")
world_sf <- world_sf |>
  filter(!name %in% c("Antarctica", "Greenland"))  # 过滤掉南极洲和格陵兰

# 创建幸福指数示例数据集
happiness_data <- data.frame(
  Country = c(
    "France", "Germany", "United Kingdom",
    "Japan", "China", "Vietnam",
    "United States of America", "Canada", "Mexico"
  ),
  Continent = c(
    "Europe", "Europe", "Europe",
    "Asia", "Asia", "Asia",
    "North America", "North America", "North America"
  ),
  Happiness_Score = rnorm(mean = 30, sd = 20, n = 9),          # 幸福指数
  GDP_per_capita = rnorm(mean = 30, sd = 20, n = 9),           # 人均GDP
  Social_support = rnorm(mean = 30, sd = 20, n = 9),           # 社会支持
  Healthy_life_expectancy = rnorm(mean = 30, sd = 20, n = 9)   # 健康预期寿命
)

# 将幸福指数数据与世界地图数据连接
world_sf <- world_sf |>
  left_join(happiness_data, by = c("name" = "Country"))    # 将幸福指数数据与世界地图数据连接

# 创建第一个图表:散点图(GDP vs 幸福指数)
p1 <- ggplot(world_sf, aes(
  GDP_per_capita,   # 人均GDP
  Happiness_Score,  # 幸福指数
  tooltip = name,   # 国家名称
  data_id = name,   # 国家名称
  color = name      # 国家名称
)) +
  geom_point_interactive(data = filter(world_sf, !is.na(Happiness_Score)), size = 4) +  # 绘制散点图
  theme_minimal() +
  theme(
    axis.title.x = element_blank(),     # 隐藏x轴标题
    axis.title.y = element_blank(),     # 隐藏y轴标题
    legend.position = "none"            # 隐藏图例
  )

# 创建第二个图表:柱状图(幸福指数排序)
p2 <- ggplot(world_sf, aes(
  x = reorder(name, Happiness_Score),  # 按幸福指数排序
  y = Happiness_Score,                 # 幸福指数
  tooltip = name,                      # 国家名称
  data_id = name,                      # 国家名称
  fill = name                          # 国家名称
)) +
  geom_col_interactive(data = filter(world_sf, !is.na(Happiness_Score))) +
  coord_flip() +                       # 翻转坐标轴
  theme_minimal() +
  theme(
    axis.title.x = element_blank(),     # 隐藏x轴标题
    axis.title.y = element_blank(),     # 隐藏y轴标题
    legend.position = "none"            # 隐藏图例
  )

# 创建第三个图表:世界地图填色图
p3 <- ggplot() +
  geom_sf(data = world_sf, fill = "lightgrey", color = "lightgrey") +  # 背景地图
  geom_sf_interactive(
    data = filter(world_sf, !is.na(Happiness_Score)), # 过滤掉没有幸福指数数据的国家
    aes(fill = name, tooltip = name, data_id = name)  # 国家名称
  ) +
  coord_sf(crs = st_crs(3857)) +       # 使用Web Mercator投影
  theme_void() +                       # 移除所有轴线和背景
  theme(
    axis.title.x = element_blank(),     # 隐藏x轴标题
    axis.title.y = element_blank(),     # 隐藏y轴标题
    legend.position = "none"            # 隐藏图例
  )

# 组合所有图表:上方两个图表并排,下方地图
combined_plot <- (p1 + p2) / p3 + plot_layout(heights = c(1, 2))

# 创建交互式图表
interactive_plot <- girafe(ggobj = combined_plot)
interactive_plot <- girafe_options(
  interactive_plot,
  opts_hover(css = "fill:red;stroke:black;")  # 设置悬停效果样式
)

# 显示交互式图表
interactive_plot

世界各国幸福指数多维度交互式可视化

刚才只高亮了一个项目, 现在可以高亮一个组中的多个项目

Show/Hide Code
# 创建第一个图表:散点图(GDP vs 幸福指数,按大洲着色)
p1 <- ggplot(world_sf, aes(
  GDP_per_capita,
  Happiness_Score,
  tooltip = name,
  data_id = Continent,
  color = Continent
)) +
  geom_point_interactive(data = filter(world_sf, !is.na(Happiness_Score)), size = 4) +
  theme_minimal() +
  theme(
    axis.title.x = element_blank(),     # 隐藏x轴标题
    axis.title.y = element_blank(),     # 隐藏y轴标题
    legend.position = "none"            # 隐藏图例
  )

# 创建第二个图表:柱状图(幸福指数排序,按大洲着色)
p2 <- ggplot(world_sf, aes(
  x = reorder(name, Happiness_Score),
  y = Happiness_Score,
  tooltip = name,
  data_id = Continent,
  fill = Continent
)) +
  geom_col_interactive(data = filter(world_sf, !is.na(Happiness_Score))) +
  coord_flip() +                       # 翻转坐标轴
  theme_minimal() +
  theme(
    axis.title.x = element_blank(),     # 隐藏x轴标题
    axis.title.y = element_blank(),     # 隐藏y轴标题
    legend.position = "none"            # 隐藏图例
  )

# 创建第三个图表:世界地图填色图(按大洲着色)
p3 <- ggplot() +
  geom_sf(data = world_sf, fill = "lightgrey", color = "lightgrey") +  # 背景地图
  geom_sf_interactive(
    data = filter(world_sf, !is.na(Happiness_Score)),
    aes(fill = Continent, tooltip = name, data_id = Continent)
  ) +
  coord_sf(crs = st_crs(3857)) +       # 使用Web Mercator投影
  theme_void() +                       # 移除所有轴线和背景
  theme(
    axis.title.x = element_blank(),     # 隐藏x轴标题
    axis.title.y = element_blank(),     # 隐藏y轴标题
    legend.position = "none"            # 隐藏图例
  )

# 组合所有图表:上方两个图表并排,下方地图
combined_plot <- (p1 + p2) / p3 + plot_layout(heights = c(1, 2))

# 创建交互式图表
interactive_plot <- girafe(ggobj = combined_plot)
interactive_plot <- girafe_options(
  interactive_plot,
  opts_hover(css = "fill:red;stroke:black;")  # 设置悬停效果样式
)

# 显示交互式图表
interactive_plot

按大洲分类的世界各国幸福指数交互式可视化

使用 CSS 美化样式: (Quarto 未正确渲染)

Show/Hide Code
# 定义工具提示样式
tooltip_css <- "
  border-radius: 12px;
  color: #333;
  background-color: white;
  padding: 10px;
  font-size: 14px;
"

# 定义悬停效果样式
hover_css <- "
  filter: brightness(75%);
  transition: all 0.3s ease;
"

# 应用交互式样式设置
interactive_plot <- interactive_plot |>
  girafe_options(
    opts_hover(css = hover_css),         # 设置悬停效果:降低亮度,平滑过渡
    opts_tooltip(css = tooltip_css)      # 设置工具提示:圆角白色背景,深色文字
  )

# 显示最终的交互式图表
interactive_plot

自定义交互式图表样式设置

更多啊, 还要更多的 CSS (Quarto 未正确渲染)

Show/Hide Code
# 定义高级工具提示样式
tooltip_css <- "
  background: linear-gradient(145deg, #f0f0f0, #e6e6e6);     # 渐变背景
  border: none;                                                  # 无边框
  border-radius: 12px;                                           # 圆角
  box-shadow: 3px 3px 10px #d1d1d1, -3px -3px 10px #ffffff;  # 阴影
  color: #333;                                                   # 文字颜色
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;  # 字体
  font-size: 14px;                                               # 字体大小
  padding: 12px;                                                 # 内边距
  transition: all 0.5s ease-out;                                 # 过渡效果
"

# 定义高级悬停效果样式
hover_css <- "
  filter: brightness(75%);                                        # 亮度变化
  cursor: pointer;                                                # 手型光标
  filter: brightness(1.2) drop-shadow(0 0 5px rgba(78, 84, 200, 0.5));  # 光晕
  transition: all 0.5s ease-out;                                 # 过渡效果
"

# 应用高级交互式样式设置
interactive_plot <- interactive_plot |>
  girafe_options(
    opts_hover(css = hover_css),         # 设置悬停效果:亮度变化+光晕+手型光标
    opts_tooltip(css = tooltip_css)      # 设置工具提示:渐变背景+3D阴影+现代字体
  )

# 显示最终的高级交互式图表
interactive_plot

高级自定义交互式图表样式设置

非悬停组模糊, 突出目标组,减弱其他组的视觉干扰: (Quarto 未正确渲染)

Show/Hide Code
# 定义工具提示样式
tooltip_css <- "
  border-radius: 12px;
  color: #333;
  background-color: white;
  padding: 10px;
  font-size: 14px;
  transition: all 0.5s ease-out;
"

# 定义悬停目标元素样式
hover_css <- "
  filter: brightness(75%);
  cursor: pointer;
  transition: all 0.5s ease-out;
  filter: brightness(1.15);
"

# 应用交互式样式设置,包含反向悬停效果
interactive_plot <- interactive_plot |>
  girafe_options(
    opts_hover(css = hover_css),                                        # 设置悬停目标:亮度增强+手型光标
    opts_tooltip(css = tooltip_css),                                    # 设置工具提示:圆角白色背景
    opts_hover_inv(css = "opacity:0.3; transition: all 0.2s ease-out;") # 设置非悬停元素:透明度30%,突出目标组
  )

# 显示具有反向悬停效果的交互式图表
interactive_plot

悬停反向效果交互式图表样式设置

32.7 操作地图

加载从网上中找到的数据:

Show/Hide Code
library(sf)
my_sf <- read_sf(
  file.path("./data/map/TM_WORLD_BORDERS_SIMPL-0.3.shp") # 注意这是4个文件
)
head(my_sf) |> knitr::kable()
FIPS ISO2 ISO3 UN NAME AREA POP2005 REGION SUBREGION LON LAT geometry
AC AG ATG 28 Antigua and Barbuda 44 83039 19 29 -61.783 17.078 MULTIPOLYGON (((-61.68667 1…
AG DZ DZA 12 Algeria 238174 32854159 2 15 2.632 28.163 MULTIPOLYGON (((2.96361 36….
AJ AZ AZE 31 Azerbaijan 8260 8352021 142 145 47.395 40.430 MULTIPOLYGON (((45.08332 39…
AL AL ALB 8 Albania 2740 3153731 150 39 20.068 41.143 MULTIPOLYGON (((19.43621 41…
AM AM ARM 51 Armenia 2820 3017661 142 145 44.563 40.534 MULTIPOLYGON (((45.15387 41…
AO AO AGO 24 Angola 124670 16095214 2 17 17.544 -12.296 MULTIPOLYGON (((11.75083 -1…
Show/Hide Code
africa <- my_sf[my_sf$REGION == 2, ]     # 非洲
par(mar = c(0, 0, 0, 0))                 # 设置图形边距为0
plot(st_geometry(africa),
  xlim = c(-20, 60), ylim = c(-40, 35),  # 设置x轴和y轴范围
  col = "steelblue", lwd = 0.5           # 设置颜色和线宽
)

绘制非洲地图

简化地理空间对象, 弯弯曲曲的边界线用几何图形近似:

Show/Hide Code
library("rmapshaper") # 简化地理空间对象
africaSimple <- ms_simplify(africa, keep = 0.01, keep_shapes = TRUE)
par(mar = c(0, 0, 0, 0))                 # 设置图形边距为0
plot(st_geometry(africaSimple),
  xlim = c(-20, 60), ylim = c(-40, 35),  # 设置x轴和y轴范围
  col = "#59b2a3", lwd = 0.5             # 设置颜色和线宽
)

简化地理空间对象

加上文字标签: 即计算每个区域的质心以添加标签。这可以使用 st_centroid() 包的 sf 函数来完成。

Show/Hide Code
# 筛选出面积大于75000平方公里的非洲大国
africaBig <- africa[which(africa$AREA > 75000), ]

# 计算大国的几何中心点(使用最大多边形)
centroids <- st_centroid(africaBig, of_largest_polygon = TRUE)

# 提取坐标并添加为新列
centers <- cbind(centroids, st_coordinates(centroids))

# 在地图上显示结果
par(mar = c(0, 0, 0, 0))                                                # 设置图边距为0
plot(st_geometry(africa), xlim = c(-20, 60), ylim = c(-40, 35), lwd = 0.5) # 绘制非洲地图轮廓
text(centers$X, centers$Y, centers$FIPS, cex = .9, col = "#69b3a2")    # 在中心点添加国家代码标签

非洲大国地图标注

32.8 2D / 3D

rayshader 包是一个创建带阴影效果的 2D 和 3D 地图的强大工具。它特别适用于创建带有浮雕效果的精美地图

Show/Hide Code
# 加载必需的包
library(rayshader)  # 3D地形可视化
library(raster)     # 栅格数据处理
library(geodata)    # 地理数据获取

# 定义大峡谷区域的地理范围
extent_gc <- extent(-113.0, -112.0, 36.0, 37.0)

# 获取SRTM高程数据(3弧秒分辨率)
srtm_gc <- elevation_3s("SRTM", lon = -112.5, lat = 36.5)

# 裁剪高程数据到指定区域
srtm_gc_cropped <- crop(srtm_gc, extent_gc)

# 将栅格数据转换为矩阵格式
elevation_matrix <- raster_to_matrix(srtm_gc_cropped)

# ----p1-----
# 基础3D地形渲染(沙漠纹理)
elevation_matrix |>
  sphere_shade(texture = "desert", sunangle = 45) |>
  plot_map()

# ----p2-----
# 创建自定义颜色纹理
custom_texture <- create_texture("#fff673", "#55967a", "#8fb28a", "#55967a", "#cfe0a9")

# 使用自定义纹理渲染
elevation_matrix |>
  sphere_shade(texture = custom_texture, sunangle = 45) |>
  plot_map()

# ----p3-----
# 高级渲染:添加阴影效果
elevation_matrix |>
  sphere_shade(texture = "desert", sunangle = 45, zscale = 50) |>
  add_shadow(ray_shade(elevation_matrix), 0.5) |>     # 添加光线追踪阴影
  add_shadow(ambient_shade(elevation_matrix), 0) |>   # 添加环境光阴影
  plot_map()

基础3D地形渲染(沙漠纹理)

创建自定义颜色纹理

高级渲染:添加阴影效果

大峡谷地区3D地形可视化