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

ggplot2双Y轴绘图:仅反转Depth轴并缩小次Y轴

问题描述

我用ggplot2绘制了以Year为X轴、Depth_cm为Y轴的折线图,还添加了代表沉积速率(Sedimentation Rate)的第二个Y轴,现有三个需求:

  • 第一个Y轴(Depth)需反转,刻度从顶部0到底部310;第二个Y轴保持正常,刻度从底部0到顶部34。
  • 尝试scale_y_reverse和trans="reverse"时,两个Y轴会同时反转,希望仅反转Depth轴。
  • 希望将第二个Y轴的尺寸缩小至参考图样式。

当前使用的R代码:

library(ggplot2)

df <- data.frame(Depth_cm = c(5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, 185, 190, 195, 200, 205, 210, 215, 220, 225, 230, 235, 240, 245, 250, 255, 260, 265, 270, 275, 280, 285, 290, 295, 300, 305, 310
),
Year = c(1859, 1712, 1565, 1418, 1272, 1125, 978, 831, 684, 537, 244, -49, -343, -636, -929, -1222, -1516, -1809, -2102, -2280, -2458, -2636, -2814, -2992, -3170, -3348, -3527, -3705, -3883, -4061, -4239, -4417, -4840, -5262, -5685, -6108, -6530, -6953, -7376, -7798, -8221, -8644, -9066, -9489, -9912, -10334, -10757, -11180, -11603, -12025, -12448, -12871, -13293, -13716, -14139, -14561, -14984, -15407, -15829, -16252, -16675, -17097),
Incertainity = c(66, 66, 66, 66, 66, 66, 66, 66, 66, 115, 115, 115, 115, 115, 115, 115, 115, 115, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133),
Rate = c(34, 34, 34, 34, 34, 34, 34, 34, 34, 17, 17, 17, 17, 17, 17, 17, 17, 17, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12))


ggplot(df, aes(x = Year, y = Depth_cm)) +
  geom_ribbon(aes(xmin = Year - Incertainity, xmax = Year + Incertainity), alpha = 0.6, fill = "green3", size = 1) +
  geom_line(aes(linetype = ifelse((Year >= 2006 & Year <= 537) | (Year >= -13716 & Year <= -17097), "solid", "dotted"))) +
  geom_point(data = df[df$Year %in% c(537, -2102, -4417, -13716),], shape = "triangle", color = "red3", size = 2) +
  geom_line(aes(y = (Rate*10)))+
  scale_y_continuous(name = "Depth", sec.axis = sec_axis(~ . /10, name = "Sedimentation rate (cm/kyr)", breaks = seq(0, 34, by = 2))) +
  scale_x_continuous(name = "Year (AD/BC)", limits = c(-17500, 2100), breaks = seq(-17500, 2100, by = 1500)) +
  labs(x = "Year (AD/BC)", y = "Depth (cm)") +
  guides(linetype = FALSE) +
  theme_classic()

当前问题:使用默认反转函数会导致两个Y轴同时反转,且次Y轴尺寸与主Y轴一致,不符合需求。目标样式为主Y轴顶部0、底部310,右侧次Y轴尺寸更小,刻度从底部0到顶部34。

解决方案

修改后的完整代码

library(ggplot2)

df <- data.frame(Depth_cm = c(5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180, 185, 190, 195, 200, 205, 210, 215, 220, 225, 230, 235, 240, 245, 250, 255, 260, 265, 270, 275, 280, 285, 290, 295, 300, 305, 310),
                 Year = c(1859, 1712, 1565, 1418, 1272, 1125, 978, 831, 684, 537, 244, -49, -343, -636, -929, -1222, -1516, -1809, -2102, -2280, -2458, -2636, -2814, -2992, -3170, -3348, -3527, -3705, -3883, -4061, -4239, -4417, -4840, -5262, -5685, -6108, -6530, -6953, -7376, -7798, -8221, -8644, -9066, -9489, -9912, -10334, -10757, -11180, -11603, -12025, -12448, -12871, -13293, -13716, -14139, -14561, -14984, -15407, -15829, -16252, -16675, -17097),
                 Incertainity = c(66, 66, 66, 66, 66, 66, 66, 66, 66, 115, 115, 115, 115, 115, 115, 115, 115, 115, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133, 133),
                 Rate = c(34, 34, 34, 34, 34, 34, 34, 34, 34, 17, 17, 17, 17, 17, 17, 17, 17, 17, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12))

# 计算Rate到Depth范围的缩放系数,确保Rate最大值34对应Depth最大值310
scale_factor <- 310 / 34

ggplot(df, aes(x = Year, y = Depth_cm)) +
  geom_ribbon(aes(xmin = Year - Incertainity, xmax = Year + Incertainity), alpha = 0.6, fill = "green3", size = 1) +
  # 修正linetype的条件判断逻辑(原条件顺序错误,导致判断失效)
  geom_line(aes(linetype = ifelse((Year >= 537 & Year <= 2006) | (Year >= -17097 & Year <= -13716), "solid", "dotted"))) +
  geom_point(data = df[df$Year %in% c(537, -2102, -4417, -13716),], shape = "triangle", color = "red3", size = 2) +
  # 调整Rate的映射,适配反转后的主Y轴
  geom_line(aes(y = 310 - Rate * scale_factor)) +
  # 主Y轴通过limits=c(310,0)实现反转,刻度从顶部0到底部310
  scale_y_continuous(
    name = "Depth (cm)",
    limits = c(310, 0),
    breaks = seq(0, 310, by = 50),
    sec.axis = sec_axis(
      # 将反转后的主Y轴数值转换回Rate,实现次轴从底部0到顶部34
      ~ (310 - .) / scale_factor,
      name = "Sedimentation rate (cm/kyr)",
      breaks = seq(0, 34, by = 2)
    )
  ) +
  scale_x_continuous(name = "Year (AD/BC)", limits = c(-17500, 2100), breaks = seq(-17500, 2100, by = 1500)) +
  guides(linetype = FALSE) +
  theme_classic() +
  # 缩小右侧次Y轴的文字、标题和刻度线尺寸
  theme(
    axis.text.y.right = element_text(size = 8),
    axis.title.y.right = element_text(size = 9),
    axis.ticks.y.right = element_line(size = 0.5)
  )

关键修改说明

  1. 仅反转主Y轴:
    放弃scale_y_reverse,改用scale_y_continuous(limits = c(310, 0))手动设置轴范围从大到小,ggplot会自动反转主Y轴刻度,且不会影响次Y轴的方向。

  2. 适配次Y轴映射:
    主Y轴反转后,Rate折线的映射需调整为y = 310 - Rate * scale_factor,确保Rate的0对应主Y轴底部(310),34对应主Y轴顶部(0);次轴通过~ (310 - .) / scale_factor将主Y轴数值转换回Rate,实现次轴从底部0到顶部34的正向刻度。

  3. 缩小次Y轴尺寸:
    通过theme调整右侧Y轴的文字、标题和刻度线大小,匹配参考图的紧凑样式。

  4. 修正折线类型判断逻辑:
    原代码中Year >= 2006 & Year <= 537的条件顺序错误,永远无法触发,修正为Year >= 537 & Year <= 2006,确保折线类型判断正常生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 12:02:00