如何用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
相关产品推荐
相关产品推荐

