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

如何按分组绘制相互错开的两条geom_segment箭头?

解决ggplot中分组箭头错开且保留箭头样式的问题

需求是按性别区分,用箭头展示obs_1与obs_2的数值差值,同时让男女两组箭头相互错开,避免重叠。

方法一:使用position_dodge直接错开(推荐)

geom_segment同样支持position参数,直接通过position_dodge即可实现同一年龄组内男女箭头的错开,同时保留箭头样式:

library(ggplot2)
library(dplyr)

data <- data.frame(sex  = c('Men', 'Men', 'Men', 'Men', 'Men', 'Women','Women','Women','Women','Women'),
                    age = c('00-49', '50-59', '60-69', '70-79', '80-89', '00-49', '50-59', '60-69', '70-79', '80-89'),
                    obs_1 = c(42.73, 12.97, 11.87, 10.34, 5.39, 49.29 , 17.69, 14.41, 10.80, 6.49),
                    obs_2 = c(15.88, 28.16, 25.98, 25.55, 18.91,21.57, 38.28, 35.28, 30.10, 23.09)
                  )

data %>% 
  ggplot(aes(color = sex)) +
  geom_segment(aes(x = obs_1, xend = obs_2,
                   y = age, yend = age), 
               linewidth = 1.2, 
               arrow = arrow(type = 'closed', length = unit(3.5, 'mm')),
               # 调整width参数控制错开幅度
               position = position_dodge(width = 0.3)) +
  labs(y = "年龄组", x = "数值") +
  theme_minimal()

方法二:手动调整y轴位置

如果需要更精细的控制,可以将分类变量age转换为数值后,给不同性别的数据添加固定偏移量:

# 给每个年龄组的男女数据添加y轴偏移
data$y_pos <- as.numeric(factor(data$age)) + ifelse(data$sex == "Men", -0.15, 0.15)

data %>% 
  ggplot(aes(color = sex)) +
  geom_segment(aes(x = obs_1, xend = obs_2,
                   y = y_pos, yend = y_pos), 
               linewidth = 1.2, 
               arrow = arrow(type = 'closed', length = unit(3.5, 'mm'))) +
  # 还原y轴刻度为原年龄组标签
  scale_y_continuous(breaks = as.numeric(factor(data$age)), 
                     labels = levels(factor(data$age))) +
  labs(y = "年龄组", x = "数值") +
  theme_minimal()

两种方法都能实现需求,方法一无需额外处理数据,更简洁高效;方法二适合需要自定义偏移幅度的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 18:46:00