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

ggplot中在次坐标轴展示无关数据的实现方法

实现独立数据框的双Y轴(含箱线图与水位线)

可以实现,但ggplot2本身不支持真正独立的双坐标轴,必须通过线性变换将次轴数据映射到主轴的数值范围内,再反向还原刻度。以下是针对你的数据的具体实现方案:

步骤1:数据预处理

首先统一日期格式,对齐两个数据集的时间维度(你的Sample数据是月中采样,River数据有当月多个日期的水位,这里我们取采样当月的水位数据用于展示趋势):

library(tidyverse)
library(lubridate)

# 模拟你的数据
river_df <- tibble(
  Date = mdy(c("1/1/23", "1/15/23", "1/30/23")),
  River_stage = c(424, 424.5, 425)
)

sample_df <- tibble(
  Date = mdy(rep("1/15/23", 3)),
  Chemical = c(15, 10, 5),
  Unit = paste0("Unit_", 1:3)
)

# 取采样当月的河流水位数据
sample_month <- month(unique(sample_df$Date))
river_aligned <- river_df %>% filter(month(Date) == sample_month)

步骤2:计算坐标轴变换系数

将河流水位数据线性映射到化学数据的Y轴范围内,确保两个数据集的数值能在同一图表中展示:

# 获取两个数据集的Y轴范围
chem_range <- range(sample_df$Chemical)
river_range <- range(river_aligned$River_stage)

# 定义正向变换(水位→化学尺度)和反向变换(化学尺度→水位)
transform_river_to_chem <- function(x) {
  (x - river_range[1]) * (chem_range[2] - chem_range[1]) / (river_range[2] - river_range[1]) + chem_range[1]
}

transform_chem_to_river <- function(x) {
  (x - chem_range[1]) * (river_range[2] - river_range[1]) / (chem_range[2] - chem_range[1]) + river_range[1]
}

步骤3:绘制双Y轴图表

主Y轴展示化学样本的箱线图,次Y轴展示河流水位,同时可添加顶部X轴辅助展示水位测量日期:

ggplot() +
  # 主图:化学样本箱线图(主Y轴)
  geom_boxplot(data = sample_df, aes(x = Date, y = Chemical), fill = "#619CFF", width = 5) +
  # 次轴数据:河流水位(已映射到主Y轴尺度)
  geom_line(data = river_aligned, aes(x = Date, y = transform_river_to_chem(River_stage)), 
            color = "#F8766D", linewidth = 1.2) +
  geom_point(data = river_aligned, aes(x = Date, y = transform_river_to_chem(River_stage)), 
             color = "#F8766D", size = 3) +
  # 添加次Y轴,应用反向变换还原水位刻度
  scale_y_continuous(
    name = "Chemical Concentration",
    sec.axis = sec_axis(~transform_chem_to_river(.), name = "River Stage")
  ) +
  # 可选:顶部X轴展示水位测量日期
  scale_x_date(
    name = "Sample Date",
    sec.axis = sec_axis(~., name = "River Measurement Date", 
                        breaks = river_aligned$Date, 
                        labels = format(river_aligned$Date, "%m/%d/%y"))
  ) +
  theme_minimal() +
  theme(
    axis.title.y.left = element_text(color = "#619CFF"),
    axis.title.y.right = element_text(color = "#F8766D"),
    axis.title.x.top = element_text(color = "#F8766D")
  )

关键说明

  • 变换核心是线性缩放,确保水位数据适配化学数据的Y轴区间,避免图表变形。
  • 若采样日期覆盖多个月份,只需调整数据过滤逻辑,按月份分组处理即可。
  • 箱线图压缩问题优先通过调整geom_boxplot的width参数或扩大图表尺寸解决,顶部X轴仅作为辅助展示水位测量时间点。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 02:57:35