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

ggplot等高线图添加带非反向对数次级轴的点数据集问题

问题描述

现有一幅带反向Y轴的ggplot等高线图,需叠加Toxin数据集,并添加非反向的对数刻度次级Y轴(因Toxin数据多数接近0且存在高值)。已尝试部分代码但无法正确组合,相关信息如下:

  • 主数据集:Sample(用于生成等高线图)
  • Toxin数据集:
    • X轴:Month_Day_Revised_Fake,取值为1.4、1.8、2.2、2.6、3、3.4、3.8、4.2、4.6、5
    • Y轴(次级轴):取值为0.29、0.05、0.05、0.24、62.01、12.84、29.84、269.57、3.64、2.78
  • 已尝试代码片段:
    • 叠加点数据:geom_point(data = Toxin, aes(x = \Month_Day_Revised_Fake`, y = Toxin), pch = 21)`
    • 添加次级轴:scale_y_continuous(sec.axis = sec_axis(trans=~.*50))
解决方案

核心修改思路

  1. 主Y轴为反向深度轴,次级Y轴需独立映射Toxin数据:先将Toxin值转换到主Y轴坐标范围,再通过sec_axis反向转换为对数刻度显示。
  2. 针对Toxin含接近0值的情况,用log1p(即log(1+x))处理,避免对数转换报错,再反向转换回原始值。

完整修改代码

# 读取主数据集
Sample<- read.csv('chl_revised_stopub.csv',header=TRUE, blank.lines.skip = TRUE,na.strings = "NA",stringsAsFactors=FALSE); 

# 生成插值数据
mba <- mba.surf(Sample[,c('Month_Day_Revised_Fake', 'Depth_m', 'Temperature_C')], 100, 100)
dimnames(mba$xyz.est$z) <- list(mba$xyz.est$x, mba$xyz.est$y)
SampleMelt <- melt(mba$xyz.est$z, varnames = c('Month_Day_Revised_Fake', 'Depth_m'), value.name = 'Temperature_C')

# 自定义主题
themebox <- function(base_family = "sans", ...){
  theme_bw(base_family = base_family, ...) +
    theme( plot.title = element_text(color="#000000",size = 14,  face = "bold"),
           axis.title.x = element_text(colour = "#000000", family="sans",size=10),
           axis.title.y = element_text(colour = "#000000", family="sans", size=10),
           axis.text.x = element_text(color="#000000", size=9, family="sans", face = 
                                        "bold"),
           axis.text.y = element_text(color="#000000", size=10, family="sans", face = "bold"))}

# 构建Toxin数据集(若未提前读取,可手动创建)
Toxin <- data.frame(
  Month_Day_Revised_Fake = c(1.4,1.8,2.2,2.6,3,3.4,3.8,4.2,4.6,5),
  Toxin_Value = c(0.29,0.05,0.05,0.24,62.01,12.84,29.84,269.57,3.64,2.78)
)

# 转换函数:将Toxin值映射到主Y轴(深度0-4的范围)
toxin_to_depth <- function(x) {
  log_val <- log1p(x)
  max_log <- log1p(max(Toxin$Toxin_Value))
  4 - (log_val / max_log) * 4  # 反向映射,让Toxin高值对应主Y轴顶部(浅水区)
}

# 反向转换函数:从深度值转回Toxin的原始值,用于次级轴显示
depth_to_toxin <- function(x) {
  log_val <- (4 - x) / 4 * log1p(max(Toxin$Toxin_Value))
  expm1(log_val)  # 还原log1p转换的值
}

# 绘制图形
Fig <-
  ggplot(data=SampleMelt, aes(Month_Day_Revised_Fake, Depth_m))+
  geom_raster(aes(fill = Temperature_C), interpolate = F, hjust = 0.5, vjust = 0.5) +
  geom_contour(aes(z = Temperature_C)) +
  # 叠加Toxin点:使用转换后的Y值匹配主Y轴坐标
  geom_point(data = Toxin, aes(x = Month_Day_Revised_Fake, y = toxin_to_depth(Toxin_Value)), 
             pch = 21, fill = "red", size = 3) +
  theme(axis.text.x = element_text(face="bold", angle = 45,hjust = 1)) +
  scale_x_continuous(guide = guide_axis(angle = 50), expand = expansion(0),
                     limits=c(1.4,5.4), 
                     breaks=c(1.4,1.8,2.2,2.6,3.0,3.4,3.8,4.2,4.6,5,5.4),
                     labels=c("1.4" = "5月26日", "1.8" = "6月13日","2.2" = "6月23日", 
                              "2.6"="7月6日", "3" = "7月21日", "3.4" = "8月9日", 
                              "3.8" = "8月24日", "4.2" = "9月20日", "4.6" = "9月30日", 
                              "5" = "10月18日", "5.4" = "11月14日"))+
  scale_y_reverse(expand = expansion(0), breaks=c(0,1.0,2.0,3.0,4.0),
                  # 添加次级Y轴:设置对数刻度标签与名称
                  sec.axis = sec_axis(trans = depth_to_toxin, 
                                      name = "毒素含量",
                                      breaks = c(0.1,1,10,100,300),
                                      labels = function(x) round(x, 1)))+
  scale_fill_gradientn(colours=matlab.like2(7),limits=c(0,22),
                       breaks=c(0,5,10,15,20,22), name="叶绿素 (\U003BCg/L)")+    
  xlab("公共码头")+
  ylab("水深 (m)")+
  themebox()

# 显示图形
print(Fig)

关键修改说明

  • Toxin数据映射:通过toxin_to_depth函数将Toxin的对数转换值缩放到主Y轴(0-4深度)范围,确保点能正确显示在图中对应位置。
  • 次级轴配置:sec_axis使用depth_to_toxin反向转换函数,将主Y轴深度值转回Toxin原始值,同时设置对数刻度断点,适配数据分布。
  • 界面汉化:将X轴日期、坐标轴标题、图例名称全部替换为中文,符合使用习惯。
  • 点样式优化:给Toxin点设置红色填充,与主图内容形成明显区分。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 03:05:40