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

如何用ggplot绘制含性别分组的双Y轴EASR/ASR折线图?

解决ggplot2双Y轴分组折线图问题

要实现X轴为Year,左Y轴对应EASR(分Male/Female/All三组)、右Y轴对应ASR(同分组)的6条折线图,关键是处理双Y轴的刻度转换,以及正确的分组映射。以下是完整解决方案:

1. 明确数据结构

假设你的数据集是长格式(若为宽格式,可先用pivot_longer转换),先构造示例数据模拟场景:

library(tidyverse)

set.seed(123)
df <- expand.grid(Year = 2010:2020, Group = c("Male", "Female", "All")) %>%
  mutate(
    EASR = runif(n(), 10, 50),
    ASR = runif(n(), 80, 200)  # 模拟与EASR范围差异较大的ASR数据
  )

2. 计算双Y轴转换比例

ggplot2的次级Y轴基于主Y轴刻度转换,需先计算ASR与EASR的范围比例,保证刻度对应真实值:

# 提取两类指标的极值范围
easr_range <- range(df$EASR)
asr_range <- range(df$ASR)

# 计算转换比例:ASR范围 / EASR范围
scale_ratio <- diff(asr_range) / diff(easr_range)

3. 绘制双Y轴分组折线图

核心是通过scale_y_continuous设置次级轴,同时对ASR数据做逆转换,确保折线位置匹配坐标:

ggplot(df, aes(x = Year)) +
  # 绘制左Y轴的EASR三组折线
  geom_line(aes(y = EASR, color = paste(Group, "EASR")), linewidth = 1) +
  # 绘制右Y轴的ASR三组折线,ASR需除以转换比例以匹配左轴刻度范围
  geom_line(aes(y = ASR / scale_ratio, color = paste(Group, "ASR")), linewidth = 1, linetype = "dashed") +
  # 设置Y轴:主轴为EASR,次级轴通过主刻度乘比例还原ASR真实值
  scale_y_continuous(
    name = "EASR",
    sec.axis = sec_axis(
      ~ . * scale_ratio,
      name = "ASR (c_rate_AllAges)"
    )
  ) +
  # 自定义颜色与图例,区分6条折线
  scale_color_manual(
    name = "指标与分组",
    values = c(
      "Male EASR" = "blue", "Female EASR" = "red", "All EASR" = "green",
      "Male ASR" = "darkblue", "Female ASR" = "darkred", "All ASR" = "darkgreen"
    )
  ) +
  labs(x = "Year", title = "EASR与ASR分性别年度趋势") +
  theme_minimal() +
  theme(legend.position = "bottom")

关键注意事项

  • 刻度转换:必须对ASR数据做/ scale_ratio转换,才能在主Y轴坐标系中正确显示,次级轴再通过~ . * scale_ratio还原ASR真实刻度。
  • 分组映射:用paste(Group, "指标")生成唯一分组标识,确保6条折线被正确区分。
  • 样式区分:用不同颜色+线型(如ASR用虚线)区分两类指标,提升图表可读性。

若你的原始数据是宽格式(比如每列对应一个分组的EASR/ASR),可先转换为长格式:

# 宽格式数据示例
wide_df <- expand.grid(Year = 2010:2020) %>%
  mutate(
    Male_EASR = runif(n(), 10, 50),
    Female_EASR = runif(n(), 10, 50),
    All_EASR = runif(n(), 10, 50),
    Male_ASR = runif(n(), 80, 200),
    Female_ASR = runif(n(), 80, 200),
    All_ASR = runif(n(), 80, 200)
  )

# 转换为长格式
long_df <- wide_df %>%
  pivot_longer(
    cols = -Year,
    names_to = c("Group", "Indicator"),
    names_sep = "_",
    values_to = "Value"
  )

# 后续按上述步骤计算比例并绘图即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 15:00:53