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

如何在ggplot2中添加第二条平行Y轴展示第三个不同缩放变量

在ggplot2中添加第三个Y轴的解决方案

嘿,这个问题我之前做项目时也碰到过!ggplot2的核心设计其实不太推荐用多个Y轴(毕竟很容易误导读者对数据相关性的判断),但如果你的场景确实需要在同一图里展示三个差异极大的变量,还是有可行的办法,我给你两种方案参考:

方案一:纯ggplot2手动实现(无需额外包)

这种方法的核心是把第三个变量缩放到主Y轴的数值范围,然后手动在图表右侧添加第三个轴的刻度和标签:

1. 准备示例数据

先造一组和你场景类似的差异数据:

library(ggplot2)
library(dplyr)

set.seed(123) # 保证结果可复现
df <- tibble(
  x = 1:10,
  y1 = runif(10, 0, 1000),  # 主变量:范围0-1000
  y2 = runif(10, 0, 1),     # 第一个次级变量:范围0-1
  y3 = runif(10, 0, 5000)   # 第三个变量:范围0-5000
)

2. 缩放第三个变量

把y3的数值映射到主Y轴(y1)的范围里:

# 计算主Y轴和第三个变量的范围
y1_min_max <- range(df$y1)
y3_min_max <- range(df$y3)

# 计算缩放因子和偏移量
scale_factor <- diff(y1_min_max) / diff(y3_min_max)
shift_val <- y1_min_max[1] - y3_min_max[1] * scale_factor

# 生成缩放后的y3列
df <- df %>% mutate(y3_scaled = y3 * scale_factor + shift_val)

3. 绘制图表并手动添加第三个轴

ggplot(df, aes(x = x)) +
  # 绘制三个变量的折线
  geom_line(aes(y = y1), color = "darkred", size = 1.2) +
  geom_line(aes(y = y2 * diff(y1_min_max) + y1_min_max[1]), color = "steelblue", size = 1.2) +
  geom_line(aes(y = y3_scaled), color = "forestgreen", size = 1.2) +
  
  # 设置主Y轴和第一个次级Y轴
  scale_y_continuous(
    name = "*Y1: 销售额*",
    sec.axis = sec_axis(
      trans = ~ (. - y1_min_max[1]) / diff(y1_min_max),
      name = "*Y2: 转化率*"
    )
  ) +
  
  # 手动添加第三个Y轴的标签、轴线和刻度
  annotate("text", x = 11, y = mean(y1_min_max), label = "*Y3: 用户数*", angle = -90, color = "forestgreen", size = 4) +
  annotate("segment", x = 10.8, xend = 10.8, y = y1_min_max[1], yend = y1_min_max[2], color = "forestgreen", linewidth = 1) +
  annotate("text", x = 10.9, y = seq(y1_min_max[1], y1_min_max[2], length.out = 5), 
           label = round(seq(y3_min_max[1], y3_min_max[2], length.out = 5)), 
           color = "forestgreen", size = 3) +
  
  # 调整主题,给右侧预留足够空间
  theme(
    axis.text.y.right = element_text(color = "steelblue"),
    axis.title.y.right = element_text(color = "steelblue"),
    plot.margin = margin(5, 35, 5, 5)
  )

方案二:用ggside包简化操作

如果不想手动计算刻度,可以用ggside包,它支持原生添加多个侧边轴:

1. 安装并加载包

install.packages("ggside")
library(ggside)

2. 快速绘制多Y轴图表

ggplot(df, aes(x = x)) +
  geom_line(aes(y = y1), color = "darkred") +
  geom_line(aes(y = y2), color = "steelblue") +
  geom_line(aes(y = y3), color = "forestgreen") +
  
  # 设置三个Y轴
  scale_y_continuous(name = "*Y1: 销售额*") +
  scale_ysidey_continuous(position = "right", name = "*Y2: 转化率*") +
  scale_ysidey_right_continuous(name = "*Y3: 用户数*") +
  
  # 调整轴的颜色和主题
  theme_ggside_void() +
  theme(
    axis.title.y.right = element_text(color = "steelblue"),
    axis.title.y.right.right = element_text(color = "forestgreen"),
    axis.text.y.right = element_text(color = "steelblue"),
    axis.text.y.right.right = element_text(color = "forestgreen")
  )

更推荐的替代方案:分面展示

其实ggplot团队不推荐多Y轴是有道理的——多个缩放比例的轴很容易让读者错误关联变量间的关系。如果可以的话,更建议用分面把三个变量分开展示,清晰又直观:

# 把数据转成长格式
df_long <- df %>% 
  select(x, y1, y2, y3) %>% 
  pivot_longer(cols = starts_with("y"), names_to = "变量", values_to = "数值")

# 绘制分面图
ggplot(df_long, aes(x = x, y = 数值, color = 变量)) +
  geom_line(size = 1.2) +
  facet_wrap(~变量, scales = "free_y", ncol = 1) +
  theme(legend.position = "none")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:02:52