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

如何在东海岸地图上用geom_curve创建按月份渐变的弯箭头并添加环形箭头组?

解决方案

实现渐变弯箭头与环形箭头组

以下是满足需求的完整代码,包含两种实现渐变箭头的方式(一种依赖ggforce包简化操作,另一种纯基础包实现):


方法1:使用ggforce快速实现渐变弯箭头

ggforce::geom_link支持单条曲线的颜色沿路径渐变,代码更简洁:

require(sf); require(maps); require(ggplot2); require(ggforce)

# 加载并筛选东海岸州地图数据
usmap <- st_as_sf(map("state", plot = F, fill = TRUE))
seaboard <- c('alabama', 'connecticut', 'georgia', 'maryland', 'mississippi', 'new jersey','new york', 'pennsylvania', 'south carolina', 'florida', 'north carolina', 'delaware','rhode island',
    'massachusetts', 'virginia')
monseq <- c('September','October','November','December')

# 定义弯箭头的起点和终点
arrow_start <- data.frame(x = -75, y = 42.5)
arrow_end <- data.frame(x = -85, y = 30.5)

# 创建环形箭头组数据:三个顺时针首尾相连的弧形箭头
ring_center <- data.frame(x = -84.5, y = 31)  # 箭头头部上方的环形中心
ring_radius <- 0.5
angles <- seq(0, 2*pi, length.out = 4)[-4]  # 三个箭头的起始角度(间隔120度)
ring_data <- data.frame(
  x = ring_center$x + ring_radius*cos(angles),
  y = ring_center$y + ring_radius*sin(angles),
  xend = ring_center$x + ring_radius*cos(angles + 2*pi/3),
  yend = ring_center$y + ring_radius*sin(angles + 2*pi/3)
)

# 绘图
ggplot() +
  # 绘制东海岸州地图
  geom_sf(data = usmap[usmap$ID %in% seaboard,], fill = "lightgrey") +
  # 绘制颜色渐变的弯箭头
  geom_link(
    data = data.frame(x = arrow_start$x, y = arrow_start$y, xend = arrow_end$x, yend = arrow_end$y),
    aes(x = x, y = y, xend = xend, yend = yend, color = stat(index)),
    size = 3,
    curvature = -0.2,
    lineend = "round",
    arrow = arrow(length = unit(0.3, "cm"))
  ) +
  # 配置颜色渐变,对应月份标签
  scale_color_gradient(
    low = "red", high = "blue",
    breaks = seq(1,4),
    labels = monseq,
    name = "Month"
  ) +
  # 绘制环形箭头组
  geom_curve(
    data = ring_data,
    aes(x = x, y = y, xend = xend, yend = yend),
    curvature = 0.5,  # 曲率设置让曲线贴合环形
    color = "black",
    arrow = arrow(length = unit(0.2, "cm"), type = "closed")
  ) +
  theme_bw() +
  coord_sf(xlim = c(-88, -67), ylim = c(28, 45))  # 聚焦东海岸区域

方法2:纯基础包实现渐变弯箭头

如果不想额外安装ggforce,可以手动拆分弯箭头为多个渐变线段:

require(sf); require(maps); require(ggplot2)

usmap <- st_as_sf(map("state", plot = F, fill = TRUE))
seaboard <- c('alabama', 'connecticut', 'georgia', 'maryland', 'mississippi', 'new jersey','new york', 'pennsylvania', 'south carolina', 'florida', 'north carolina', 'delaware','rhode island',
    'massachusetts', 'virginia')
monseq <- c('September','October','November','December')
n_segments <- 100  # 拆分的渐变段数量

# 定义弯箭头参数
start_x <- -75; start_y <- 42.5
end_x <- -85; end_y <- 30.5
curvature <- -0.2

# 计算弯曲线上的所有点(模拟geom_curve的曲线逻辑)
t <- seq(0, 1, length.out = n_segments)
x <- start_x + t*(end_x - start_x) + curvature*(start_y - end_y)*(t - t^2)
y <- start_y + t*(end_y - start_y) + curvature*(end_x - start_x)*(t - t^2)

# 生成分段渐变的线段数据
arrow_segments <- data.frame(
  x = x[-n_segments],
  y = y[-n_segments],
  xend = x[-1],
  yend = y[-1],
  color_val = seq(1, 4, length.out = n_segments - 1)
)

# 环形箭头组数据
ring_center <- data.frame(x = -84.5, y = 31)
ring_radius <- 0.5
angles <- seq(0, 2*pi, length.out = 4)[-4]
ring_data <- data.frame(
  x = ring_center$x + ring_radius*cos(angles),
  y = ring_center$y + ring_radius*sin(angles),
  xend = ring_center$x + ring_radius*cos(angles + 2*pi/3),
  yend = ring_center$y + ring_radius*sin(angles + 2*pi/3)
)

# 绘图
ggplot() +
  geom_sf(data = usmap[usmap$ID %in% seaboard,], fill = "lightgrey") +
  # 绘制分段渐变的线段
  geom_segment(
    data = arrow_segments,
    aes(x = x, y = y, xend = xend, yend = yend, color = color_val),
    size = 3,
    lineend = "round"
  ) +
  # 单独绘制带箭头的最后一段(对应12月的蓝色)
  geom_curve(
    data = data.frame(x = x[n_segments-1], y = y[n_segments-1], xend = end_x, yend = end_y),
    aes(x = x, y = y, xend = xend, yend = yend),
    color = "blue",
    size = 3,
    curvature = curvature,
    lineend = "round",
    arrow = arrow(length = unit(0.3, "cm"))
  ) +
  scale_color_gradient(
    low = "red", high = "blue",
    breaks = seq(1,4),
    labels = monseq,
    name = "Month"
  ) +
  # 绘制环形箭头组
  geom_curve(
    data = ring_data,
    aes(x = x, y = y, xend = xend, yend = yend),
    curvature = 0.5,
    color = "black",
    arrow = arrow(length = unit(0.2, "cm"))
  ) +
  theme_bw() +
  coord_sf(xlim = c(-88, -67), ylim = c(28, 45))

关键说明

  • 渐变弯箭头:方法1用geom_link自动处理路径渐变;方法2通过拆分曲线为多个线段,每个线段对应一个渐变颜色值,实现近似渐变效果。
  • 环形箭头组:通过计算三个间隔120度的弧形箭头坐标,用geom_curve绘制首尾相连的顺时针环形,曲率设为0.5让曲线贴合圆形。
  • 地图优化:调整coord_sf的坐标范围,聚焦东海岸区域,让箭头和环形更突出。

内容的提问来源于stack exchange,提问作者Seth W. Bigelow

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 10:05:25