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

如何用ggplot2为Levey-Jennings图添加指定时段的次Y轴

问题需求

我已经用主数据框绘制了Levey-Jennings图,现在想用ggplot2把另一个数据框中2022年8月18日至2022年9月27日的数据以次Y轴的形式添加到图中。


次数据框结构

structure(list(DDATE = c("27.09.22", "21.09.22", "19.09.22", 
"18.09.22", "15.09.22", "13.09.22", "11.09.22", "06.09.22", "04.09.22", 
"01.09.22", "30.08.22", "28.08.22", "21.08.22", "18.08.22", NA
), LOT.REACTIFS = c("38279BE00", "38279BE00", "38279BE00", "38279BE00", 
"38279BE00", "38279BE00", "38279BE00", "38279BE00", "38279BE00", 
"38279BE00", "38279BE00", "38279BE00", "38279BE00", "38279BE00", 
NA), RESULTAT = c(0.76, 0.76, 0.83, 0.64, 0.68, 0.68, 0.7, 0.65, 
0.81, 0.75, 0.77, 0.74, 0.79, 0.77, NA)), row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", 
"14", "NA"), class = "data.frame")

主数据框结构

structure(list(DDATE = c("17.07.22", "18.07.22", "19.07.22", 
"20.07.22", "21.07.22", "24.07.22", "25.07.22", "26.07.22", "27.07.22", 
"28.07.22", "31.07.22", "01.08.22", "02.08.22", "03.08.22", "04.08.22", 
"04.08.22", "07.08.22", "09.08.22", "10.08.22", "14.08.22", "15.08.22", 
"16.08.22", "18.08.22", "21.08.22", "28.08.22", "30.08.22", "01.09.22", 
"04.09.22", "06.09.22", "11.09.22", "13.09.22", "15.09.22", "18.09.22", 
"19.09.22", "21.09.22", "25.09.22", "27.09.22", "29.09.22"), 
    LOT.REACTIFS = c("88015LI00", "88015LI00", "88015LI00", "88015LI00", 
    "88015LI00", "88015LI00", "88015LI00", "88015LI00", "88015LI00", 
    "88015LI00", "88015LI00", "88015LI00", "88015LI00", "88015LI00", 
    "88015LI00", "88015LI00", "88015LI00", "88015LI00", "88015LI00", 
    "88015LI00", "88015LI00", "88015LI00", "38279BE00", "38279BE00", 
    "38279BE00", "38279BE00", "38279BE00", "38279BE00", "38279BE00", 
    "38279BE00", "38279BE00", "38279BE00", "38279BE00", "38279BE00", 
    "38279BE00", "38279BE00", "38279BE00", "03373BE00"), RESULTAT = c(0.66, 
    0.62, 0.71, 0.76, 0.79, 0.69, 0.7, 0.77, 0.67, 0.69, 0.74, 
    0.66, 0.62, 0.71, 0.69, 0.74, 0.69, 0.74, 0.66, 0.77, 0.7, 
    0.74, 0.61, 0.62, 0.58, 0.61, 0.6, 0.64, 0.51, 0.56, 0.53, 
    0.54, 0.5, 0.66, 0.6, 0.78, 0.6, 0.75)), row.names = 10:47, class = "data.frame")

当前使用代码

library(ggplot2)
library(ggthemes)
# Basic scatter plot
Plot3 = ggplot(PSAT, aes(x=temp1, y=DATO2$value))+geom_line( color="grey") +  geom_point(shape=21, color="black", fill="#69b3a2", size=1)+
  geom_point(mapping = aes(x = temp1, y = DATO2$value, color = DATO2$LOT.REACTIFS))+ 
  scale_y_continuous("Precipitation", sec.axis = sec_axis(~ .*17142/13553, name = "Temperature" ))
Plot3

解决方案

步骤1:统一日期格式并筛选目标数据

先把两个数据框的日期转换成标准格式,同时提取次数据框中指定时间范围的记录:

library(dplyr)
library(lubridate)

# 处理主数据框:转换日期格式并排序
main_df <- main_df %>%
  mutate(DDATE = dmy(DDATE)) %>%
  arrange(DDATE) %>%
  filter(!is.na(DDATE))

# 处理次数据框:筛选时间范围+转换日期格式
secondary_df <- secondary_df %>%
  filter(!is.na(DDATE)) %>%
  mutate(DDATE = dmy(DDATE)) %>%
  filter(DDATE >= ymd("2022-08-18") & DDATE <= ymd("2022-09-27")) %>%
  arrange(DDATE)

步骤2:计算次Y轴的转换系数

ggplot2的次Y轴是视觉映射,需要将次数据的数值范围转换到主数据的范围内,避免数据溢出:

# 获取主、次数据的结果值范围
main_range <- range(main_df$RESULTAT, na.rm = TRUE)
sec_range <- range(secondary_df$RESULTAT, na.rm = TRUE)

# 计算转换公式:把次数据映射到主数据的刻度区间
scale_factor <- (main_range[2] - main_range[1]) / (sec_range[2] - sec_range[1])
shift_factor <- main_range[1] - sec_range[1] * scale_factor

# 定义转换函数:次数据 → 主数据刻度
sec_to_main <- function(x) x * scale_factor + shift_factor
# 定义逆转换函数:主数据刻度 → 次数据显示值
main_to_sec <- function(x) (x - shift_factor) / scale_factor

步骤3:绘制带次Y轴的Levey-Jennings图

用不同的样式区分主、次数据,添加次Y轴并设置标签:

library(ggplot2)

p <- ggplot(main_df, aes(x = DDATE, y = RESULTAT)) +
  # 主数据:线条+带填充的点(按试剂批号区分)
  geom_line(color = "grey", alpha = 0.7) +
  geom_point(aes(fill = LOT.REACTIFS), shape = 21, color = "black", size = 2) +
  # 次数据:虚线+三角点
  geom_line(data = secondary_df, aes(y = sec_to_main(RESULTAT)), color = "red", linetype = "dashed") +
  geom_point(data = secondary_df, aes(y = sec_to_main(RESULTAT)), shape = 17, color = "red", size = 2) +
  # 设置双Y轴
  scale_y_continuous(
    name = "主数据检测结果",
    sec.axis = sec_axis(trans = main_to_sec, name = "次数据检测结果")
  ) +
  # X轴日期格式化,避免重叠
  scale_x_date(date_labels = "%d-%b-%y", date_breaks = "1 week") +
  labs(x = "日期", fill = "试剂批号") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

# 展示图形
print(p)

关键说明

  • 次Y轴仅为视觉展示,实际绘图使用的是转换后的数值,确保两个数据集在同一坐标系内
  • 用颜色、线型、点型区分主、次数据,避免混淆
  • 统一日期格式后,X轴会自动按时间顺序排列

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 09:37:35