如何在ggplot中为沉积物岩芯OC%图添加非线性深度Y轴
在ggplot中为OC%关联图添加深度次坐标轴
问题背景
我有一组沉积物岩芯数据,想要绘制OC%与年龄、深度的关联图。目前已经能分别画出OC%与年龄、OC%与深度的散点图,但希望在同一张图中同时展示年龄(主Y轴)和深度(次Y轴)——由于沉积物压缩效应,年龄与深度并非线性关系,需要让次轴刻度准确对应每个数据点的深度值。
模拟数据如下:
OC<-c(0.3,0.2,0.1,0.2,0.1,0.1,0.01,0.009) depth<-c(0,1,2,3,4,5,6,7) age<-c(0,5,8,12,20,30,60,100) age<-2022-age data<-data.frame(OC,depth,age)
当前已实现的单轴图:
- OC%与年龄的散点图:

- OC%与深度的散点图:

解决方案
可以在ggplot中通过自定义坐标转换函数实现非线性对应的次坐标轴,具体实现如下:
完整代码
# 准备数据 OC<-c(0.3,0.2,0.1,0.2,0.1,0.1,0.01,0.009) depth<-c(0,1,2,3,4,5,6,7) age<-c(0,5,8,12,20,30,60,100) age<-2022-age data<-data.frame(OC,depth,age) # 创建深度与年龄的双向插值转换函数(适配非线性关系) depth_to_age <- approxfun(data$depth, data$age) age_to_depth <- approxfun(data$age, data$depth) # 绘制带双Y轴的关联图 ggplot(data,aes(x = OC, y = age))+ geom_point(size = 2, color = "#2c3e50")+ theme_classic()+ scale_y_continuous( limits = c(1920,2022), name = "年份", # 添加深度次坐标轴 sec.axis = sec_axis( trans = ~ age_to_depth(.), # 将主轴的年龄值转换为对应的深度 name = "深度(cm)", breaks = data$depth, # 使用数据中的深度值作为次轴刻度 labels = data$depth ) )+ xlab("OC%")+ theme( axis.title.y.right = element_text(color = "#e74c3c"), axis.text.y.right = element_text(color = "#e74c3c") ) # 给次轴添加颜色区分,提升可读性
代码说明
- 转换函数创建:用
approxfun生成深度与年龄的双向插值函数,因为两者是非线性关系,插值能保证刻度转换的准确性。 - 次轴设置:通过
sec.axis参数添加次坐标轴,用trans参数指定从年龄到深度的转换规则,同时设置次轴的刻度为数据中实际的深度值,确保每个数据点的深度与年龄一一对应。 - 视觉优化:给次轴添加不同颜色,避免主、次轴混淆。
注意事项
ggplot官方并不推荐过度使用次坐标轴,因为容易造成数据解读歧义,但在深度与年龄有明确一一对应关系的沉积物岩芯数据场景下,这种实现方式是合理且实用的。
内容的提问来源于stack exchange,提问作者Kelly James
相关产品推荐
相关产品推荐

