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

如何在ggplot中对坐标轴做对数缩放且不干扰线性回归模型?

问题:对数缩放X轴时保持原线性回归模型不变

我有一组qPCR标准曲线数据,需要拟合Ct ~ log(浓度)的线性模型,同时希望对X轴做对数缩放以更好展示低浓度数据,但添加scale_x_continuous(trans="log2")后模型发生了变化,如何同时实现X轴对数缩放和保留原回归模型?

数据示例

data <- structure(list(standard_conc_ngul = c(50, 50, 50, 5, 5, 0.5, 
0.5, 0.05, 0.05, 0.005, 0.005, 0.005), ct = c(18.3305377960205, 
18.133768081665, 17.8813705444336, 21.5002365112305, 21.4915542602539, 
22.7616996765137, 23.6836719512939, 25.3699340820312, 25.3488445281982, 
28.984302520752, 26.7397594451904, 27.8844776153564)), row.names = c(NA, 
-12L), class = c("tbl_df", "tbl", "data.frame"))

原拟合代码(r²=0.973):

ggplot(data, aes(x = standard_conc_ngul, y = ct)) +
  geom_point() +
  stat_smooth(method = lm, formula = y ~ log(x)) +
  stat_poly_eq(formula = y ~ log(x),
               aes(label = paste(after_stat(eq.label), after_stat(rr.label), sep = "~~~")),
               parse = TRUE, coef.digits = 3, f.digits = 3, p.digits = 3, 
               rr.digits = 3)

解决方案

核心问题是:X轴做对数缩放后,ggplot会自动将x值转换为对数形式,此时仍用y ~ log(x)会导致二次对数转换,模型偏离。只需调整回归公式匹配轴的转换逻辑即可。

方法1:直接在绘图时调整公式

library(ggplot2)
library(ggpmisc)

ggplot(data, aes(x = standard_conc_ngul, y = ct)) +
  geom_point() +
  # 对数缩放X轴,手动设置刻度匹配数据点
  scale_x_continuous(trans = "log2",
                     breaks = c(0.005, 0.05, 0.5, 5, 50),
                     labels = as.character(c(0.005, 0.05, 0.5, 5, 50))) +
  # X轴已做对数转换,模型改为y ~ x,等价于原模型y ~ log(x)
  stat_smooth(method = lm, formula = y ~ x, se = TRUE) +
  # 保留原公式用于显示标签,保证r²和原模型一致
  stat_poly_eq(formula = y ~ log(x),
               aes(label = paste(after_stat(eq.label), after_stat(rr.label), sep = "~~~")),
               parse = TRUE, coef.digits = 3, rr.digits = 3) +
  labs(x = "标准浓度 (ng/μL)", y = "Ct值") +
  theme_bw()

方法2:提前转换数据(更直观)

先对浓度做对数转换,再拟合线性模型,X轴显示原始浓度标签:

library(ggplot2)
library(ggpmisc)

# 提前计算log2转换后的浓度
data$log2_conc <- log2(data$standard_conc_ngul)

ggplot(data, aes(x = log2_conc, y = ct)) +
  geom_point() +
  stat_smooth(method = lm, formula = y ~ x, se = TRUE) +
  # 自定义标签显示原始变量的模型形式
  stat_poly_eq(formula = y ~ x,
               aes(label = paste("Ct = ", after_stat(coef.labels)[1], " + ", after_stat(coef.labels)[2], "*log2(conc)", "~~~", after_stat(rr.label), sep = "")),
               parse = TRUE, coef.digits = 3, rr.digits = 3) +
  # X轴刻度映射回原始浓度值
  scale_x_continuous(breaks = log2(c(0.005, 0.05, 0.5, 5, 50)),
                     labels = as.character(c(0.005, 0.05, 0.5, 5, 50))) +
  labs(x = "标准浓度 (ng/μL)", y = "Ct值") +
  theme_bw()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 12:40:43