You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用ggplot2或levelplot生成ArcGIS风格的独立地图图例

嘿,我来帮你搞定这个需求!下面分别用ggplot2和levelplot两种工具实现流域名称替换+ArcGIS风格独立图例,直接上可运行的代码和解释:

先准备样本数据

首先模拟一组流域空间数据,包含原始名称、要替换的新名称,以及用于着色的数值字段:

# 加载所需包
library(sf)
library(ggplot2)
library(rasterVis)
library(cowplot) # 用于组合独立图例(可选)

# 模拟流域多边形数据
watersheds <- st_sfc(
  st_polygon(list(rbind(c(0,0), c(0,2), c(2,2), c(2,0), c(0,0)))),
  st_polygon(list(rbind(c(2,0), c(2,2), c(4,2), c(4,0), c(2,0)))),
  st_polygon(list(rbind(c(0,2), c(0,4), c(2,4), c(2,2), c(0,2)))),
  st_polygon(list(rbind(c(2,2), c(2,4), c(4,4), c(4,2), c(2,2))))
) %>%
  st_sf(
    id = 1:4,
    old_name = c("流域A", "流域B", "流域C", "流域D"),
    new_name = c("长江上游", "长江中游", "黄河上游", "黄河中游"), # 替换后的新名称
    value = c(10, 25, 18, 32) # 用于地图着色的数值
  )

方法一:用ggplot2实现

核心操作:

  1. 替换流域名称:直接调用geom_sf_text()指定新名称字段
  2. 生成ArcGIS风格独立图例:通过guides()和theme()调整图例的边框、背景、位置,模拟ArcGIS的悬浮图例效果
# ggplot2绘图代码
ggplot() +
  # 绘制流域多边形
  geom_sf(data = watersheds, aes(fill = value), color = "black", linewidth = 0.8) +
  # 替换为新的流域名称标注(白色粗体更醒目)
  geom_sf_text(data = watersheds, aes(label = new_name), color = "white", size = 4, fontface = "bold") +
  # 设置渐变配色(可选替换为ArcGIS常用配色)
  scale_fill_viridis_c(option = "viridis", name = "流域指数") +
  # 调整图例样式:添加边框、刻度,设置标题位置
  guides(fill = guide_colorbar(
    title.position = "top",
    title.hjust = 0.5,
    barwidth = 15,
    barheight = 1,
    frame.colour = "black",
    ticks.colour = "black"
  )) +
  # 调整主题,适配地图风格
  theme_minimal() +
  theme(
    legend.position = "bottom", # 可改为"right"/"left"自定义位置
    legend.box = "horizontal",
    legend.background = element_rect(fill = "white", color = "black"), # 图例白色背景+黑色边框
    legend.margin = margin(5,5,5,5),
    plot.title = element_text(hjust = 0.5, size = 14, face = "bold"),
    axis.text = element_blank(), # 隐藏坐标轴文字
    axis.ticks = element_blank() # 隐藏坐标轴刻度
  ) +
  labs(title = "流域分布图(替换名称+ArcGIS风格图例)")

进阶:完全独立的图例

如果想要图例和绘图区域完全分开(和ArcGIS布局一致),可以用cowplot包提取图例后组合:

# 先绘制不带图例的地图
p_map <- ggplot() +
  geom_sf(data = watersheds, aes(fill = value), color = "black", linewidth = 0.8) +
  geom_sf_text(data = watersheds, aes(label = new_name), color = "white", size = 4, fontface = "bold") +
  scale_fill_viridis_c(option = "viridis", name = "流域指数") +
  theme_minimal() +
  theme(
    legend.position = "none", # 隐藏图例
    plot.title = element_text(hjust = 0.5, size = 14, face = "bold"),
    axis.text = element_blank(),
    axis.ticks = element_blank()
  ) +
  labs(title = "流域分布图")

# 单独生成图例
p_legend <- cowplot::get_legend(
  ggplot() +
    geom_sf(data = watersheds, aes(fill = value)) +
    scale_fill_viridis_c(option = "viridis", name = "流域指数") +
    guides(fill = guide_colorbar(
      title.position = "top",
      title.hjust = 0.5,
      barwidth = 15,
      barheight = 1,
      frame.colour = "black",
      ticks.colour = "black"
    )) +
    theme(
      legend.background = element_rect(fill = "white", color = "black"),
      legend.margin = margin(5,5,5,5)
    )
)

# 组合地图和图例
cowplot::plot_grid(p_map, p_legend, ncol = 1, rel_heights = c(4, 1))

方法二:用levelplot(rasterVis包)实现

levelplot适合处理栅格数据,也可以兼容矢量数据(需转换为sp对象),核心操作类似:

# 转换sf对象为sp对象(适配levelplot)
watersheds_sp <- as(watersheds, "Spatial")

# levelplot绘图代码
levelplot(value ~ 1, data = watersheds_sp, 
          col.regions = viridis::viridis(100), # 渐变配色
          main = list(label = "流域分布图(替换名称+ArcGIS风格图例)", cex = 1.2),
          # 设置ArcGIS风格图例
          colorkey = list(
            space = "bottom", # 图例位置
            width = 0.8,
            height = 0.1,
            box = list(col = "black"), # 图例边框
            axis.line = list(col = "black"), # 刻度线
            labels = list(cex = 0.8),
            title = list(label = "流域指数", cex = 0.9, font = 2)
          ),
          # 隐藏坐标轴
          scales = list(draw = FALSE),
          # 自定义面板,添加替换后的流域名称标注
          panel = function(x, y, ...) {
            panel.levelplot(x, y, ...)
            # 获取每个流域的中心点坐标
            coords <- coordinates(watersheds_sp)
            # 添加新名称标注(白色粗体)
            text(coords[,1], coords[,2], labels = watersheds_sp$new_name, 
                 col = "white", font = 2, cex = 0.9)
          })

一些实用提示

  • 配色可以替换为ArcGIS常用的配色,比如用RColorBrewer包的brewer.pal()函数;
  • 如果原始数据是栅格,levelplot可以直接读取栅格对象,标注可以通过提取流域边界的中心点坐标实现;
  • 标注位置可以根据实际流域形状调整,比如用st_centroid()计算更准确的中心点。

内容的提问来源于stack exchange,提问作者code123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:54:00