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

在ggplot绘制的撒丁岛地图中添加自定义图例的技术问题

解决ggplot2绘制撒丁岛地图的自定义图例问题

使用ggplot2绘制包含意大利NUTS2、NUTS3边界、研究网格及大气模拟起始点的撒丁岛地图时,无法添加符合需求的自定义图例(要求:蓝色实线=NUTS2边界、棕色实线=NUTS3边界、黑色虚线=研究网格、红色点=模拟起始点)。尝试混用base R的legend()函数时,出现错误:Error: (converted from warning) Duplicated aesthetics after name standardisation: fontface。

错误原因分析

  • 绘图系统不兼容:ggplot2基于网格系统,不能直接与base R的绘图函数(如legend())混用,强行拼接会导致渲染冲突。
  • 重复美学参数:代码中annotate()部分重复设置了fontface参数(同时写了fontface = "italic"和fontface = "bold"),这是触发报错的直接原因。

解决方案:用ggplot2原生方式构建统一图例

以下是修正后的完整代码,通过ggplot2的美学映射和虚拟图层实现自定义图例:

# 加载所需包
library(giscoR)
library(sf)
library(ggplot2)
library(ggspatial)

# 获取意大利NUTS2和NUTS3区域
nuts2_italy <- gisco_get_nuts(year="2021", nuts_level = 2, country = "Italy")
sardinia_nuts2 <- nuts2_italy[nuts2_italy$NUTS_NAME=='Sardegna',]

nuts3_italy <- gisco_get_nuts(year="2021", nuts_level = 3, country = "Italy")

# 加载模拟起始点
start_pt <- st_read("data/HYSPLIT_start_points/start_points.shp")

# 构建地图
map <- ggplot() +
  # NUTS3边界:映射颜色到图例
  geom_sf(data=nuts3_italy, fill = "antiquewhite", 
          aes(color = "NUTS3 borders"), show.legend = "line") +
  # NUTS2边界:映射颜色到图例
  geom_sf(data=sardinia_nuts2, fill = NA, 
          aes(color = "NUTS2 border"), show.legend = "line") +
  # 模拟起始点:映射颜色到图例
  geom_sf(data=start_pt, aes(color = "Initiation points"), size=1) +
  # 研究网格虚拟图层:用于生成图例项
  geom_sf(data = sardinia_nuts2, fill = NA, color = NA,
          aes(linetype = "study grid"), show.legend = "line") +
  
  # 设置坐标范围
  coord_sf(xlim = c(7.5, 10.5), ylim = c(38.7, 41.3), expand = TRUE) +
  
  # 比例尺和指北针
  annotation_scale(location = "bl", width_hint = 0.5, text_family = "serif",
                   bar_cols = c("#887e6a", "#fffff3")) +
  annotation_north_arrow(location = "br", which_north = "true", 
                         pad_x = unit(0.75, "cm"), pad_y = unit(0.2, "cm"),
                         style = north_arrow_fancy_orienteering(
                           fill = c("#887e6a", "#fffff3"),
                           line_col = "#887e6a",
                           text_family = "serif"
                         )) +
  
  # 修复重复fontface问题:合并为italic.bold
  annotate(geom = "text", x = 9, y = 40.7, label = "Sardinia", 
           fontface = "italic.bold", size = 5, family = "serif", color="#887e6a") +
  
  # 定义图例颜色映射
  scale_color_manual(
    name = "",
    values = c(
      "NUTS2 border" = "blue",
      "NUTS3 borders" = "#887e6a",
      "Initiation points" = "red"
    ),
    guide = guide_legend(order = 1)
  ) +
  # 定义图例线型映射
  scale_linetype_manual(
    name = "",
    values = c("study grid" = "dashed"),
    guide = guide_legend(order = 2)
  ) +
  
  # 坐标轴标签
  labs(x="Longitude", y="Latitude") +
  
  # 主题设置
  theme(
    panel.grid.major = element_line(color = gray(.5), linetype = "dashed", size = 0.5), 
    panel.background = element_rect(fill = "aliceblue"),
    panel.border = element_rect(colour = "#887e6a", fill = NA, size = 1.5),
    axis.text = element_text(family = "serif", colour = "#887e6a"),
    legend.position = "topright",
    legend.text = element_text(family = "serif")
  )

# 显示地图
map

关键调整说明

  1. 修复annotate()中重复的fontface参数,改为fontface = "italic.bold"。
  2. 为每个需要图例的图层添加aes()映射,通过scale_color_manual和scale_linetype_manual统一控制图例样式与标签。
  3. 添加虚拟geom_sf图层,解决研究网格(theme元素)无法直接加入图例的问题。
  4. 移除base R的legend()函数,完全使用ggplot2原生逻辑构建图例,避免系统冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 18:05:56