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

如何制作带方向箭头、变宽线条且双向流不重叠的流向地图

实现双向不重叠的流向曲线地图(基于ggplot2)

要实现类似Axios的流向地图,同时满足曲线展示流动、线宽对应流量、箭头指示方向、双向线条不重叠的需求,用ggplot2可以通过「偏移曲线+映射美学属性」的方式实现,以下是具体方案:

核心思路

  1. 为双向流动(A→B和B→A)的曲线添加不同方向的微小偏移,避免线条重叠;
  2. 用geom_curve绘制带弧度的流向曲线,通过arrow()参数添加流向箭头;
  3. 将流量数值映射到size属性,实现线宽随流量变化;
  4. 叠加地图底图作为背景(可选,用内置的地图数据即可)。

完整代码示例

library(ggplot2)
library(dplyr)

# 1. 构造示例数据:区域坐标 + 双向流量数据
region_coords <- tibble(
  region = c("California", "Texas", "New York"),
  lon = c(-119.4179, -99.9018, -74.0060),
  lat = c(36.7783, 31.9686, 40.7128)
)

flow_data <- tibble(
  origin = c("California", "Texas", "New York", "Texas", "New York", "California"),
  dest = c("Texas", "New York", "California", "California", "Texas", "New York"),
  flow = c(120, 80, 95, 70, 65, 100)
)

# 2. 合并坐标数据,为双向流动添加偏移量
flow_with_coords <- flow_data %>%
  left_join(region_coords, by = c("origin" = "region")) %>%
  rename(lon_origin = lon, lat_origin = lat) %>%
  left_join(region_coords, by = c("dest" = "region")) %>%
  rename(lon_dest = lon, lat_dest = lat) %>%
  # 为双向线条添加偏移:A→B加经度正偏移,B→A加经度负偏移(可根据区域调整方向)
  mutate(
    offset = if_else(paste(origin, dest) < paste(dest, origin), 0.5, -0.5),
    lon_origin = lon_origin + offset,
    lon_dest = lon_dest + offset
  )

# 3. 绘制流向地图
ggplot() +
  # 叠加美国州地图底图(可选)
  geom_polygon(data = map_data("state"), aes(x = long, y = lat, group = group),
               fill = "#f0f0f0", color = "#cccccc") +
  # 绘制流向曲线:线宽映射流量,添加箭头
  geom_curve(data = flow_with_coords,
             aes(x = lon_origin, y = lat_origin,
                 xend = lon_dest, yend = lat_dest,
                 size = flow),
             color = "#2c3e50", curvature = 0.2,
             arrow = arrow(length = unit(0.2, "cm"), type = "closed")) +
  # 调整线宽范围,避免过粗/过细
  scale_size_continuous(range = c(0.5, 3)) +
  # 调整地图投影和范围(聚焦示例区域)
  coord_map(xlim = c(-125, -65), ylim = c(25, 45)) +
  theme_minimal() +
  theme(legend.position = "bottom",
        axis.text = element_blank(),
        axis.title = element_blank())

关键细节说明

  • 双向偏移:通过if_else判断流动对的顺序,给A→B和B→A的起点/终点坐标添加相反方向的偏移(示例用了经度方向,也可根据区域调整为纬度方向),确保线条不重叠;
  • 曲线与箭头:geom_curve的curvature参数控制曲线弧度,arrow()参数可自定义箭头大小、样式;
  • 线宽映射:scale_size_continuous的range参数可以手动调整线宽的显示范围,避免流量差异过大导致线条过粗或过细;
  • 底图适配:如果需要更精细的区域地图,可以替换map_data("state")为对应区域的地理数据(比如城市、县区级数据)。

替代方案

如果需要更复杂的曲线样式,也可以使用ggforce包的geom_bezier来绘制贝塞尔曲线,通过添加额外的控制点来实现更灵活的偏移,核心逻辑和上述方案一致——为双向流动设置不同的控制点偏移。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 07:42:45