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

如何在ggplot的对数坐标轴上绘制geom_errorbar误差棒?

对数Y轴下带误差棒的折线图绘制方案

问题原因

你当前的对数轴绘图代码失效,核心有两个问题:

  1. 算术标准差的下限(mean - sd)可能出现非正值,而对数尺度无法显示0或负数;
  2. 对数尺度下,算术均值和标准差的统计逻辑不匹配——对数正态分布的数据,应该用几何均值和几何标准差来描述集中趋势和离散程度,算术统计量在对数轴上的误差棒不对称且无统计意义。

解决方案

我们需要基于对数转换后的计算来生成误差棒,本质是计算几何均值和几何标准差,再转换回原始尺度。

方法1:提前汇总统计量

先对数据分组计算几何均值、几何标准差对应的上下限(处理time=0的0值情况):

library(dplyr)
library(ggplot2)

# 汇总几何统计量
dat_summarised_log <- dat |>
  group_by(time) |>
  summarise(
    # 处理time=0的dv全为0的情况
    geom_mean = if(all(dv == 0)) 0 else exp(mean(log(dv[dv > 0]), na.rm = TRUE)),
    geom_sd_low = if(all(dv == 0)) 0 else exp(mean(log(dv[dv > 0]), na.rm = TRUE) - sd(log(dv[dv > 0]), na.rm = TRUE)),
    geom_sd_high = if(all(dv == 0)) 0 else exp(mean(log(dv[dv > 0]), na.rm = TRUE) + sd(log(dv[dv > 0]), na.rm = TRUE))
  )

# 绘制对数轴折线图
dat_summarised_log |>
  ggplot(aes(x = time, y = geom_mean)) +
  geom_point(size = 3) +
  geom_line(linewidth = 0.8) +
  geom_errorbar(aes(ymin = geom_sd_low, ymax = geom_sd_high), width = 0.1) +
  scale_y_log10(limits = c(0.01, 2)) + # 避开0值,确保对数轴正常显示
  theme_classic(base_size = 20)

方法2:直接在ggplot中计算(无需提前汇总)

使用stat_summary函数,在绘图时动态计算几何统计量:

# 过滤time=0的0值,或保留后通过limits避开
dat |>
  ggplot(aes(x = time, y = dv)) +
  # 绘制几何均值点
  stat_summary(
    fun = function(x) if(all(x == 0)) 0 else exp(mean(log(x[x > 0]))),
    geom = "point", size = 3
  ) +
  # 绘制几何均值线
  stat_summary(
    fun = function(x) if(all(x == 0)) 0 else exp(mean(log(x[x > 0]))),
    geom = "line", linewidth = 0.8
  ) +
  # 绘制几何标准差误差棒
  stat_summary(
    fun.data = function(x) {
      if(all(x == 0)) {
        data.frame(y = 0, ymin = 0, ymax = 0)
      } else {
        log_mean <- mean(log(x[x > 0]))
        log_sd <- sd(log(x[x > 0]))
        data.frame(
          y = exp(log_mean),
          ymin = exp(log_mean - log_sd),
          ymax = exp(log_mean + log_sd)
        )
      }
    },
    geom = "errorbar", width = 0.1
  ) +
  scale_y_log10(limits = c(0.01, 2)) +
  theme_classic(base_size = 20)

关键说明

  • 几何均值 = exp(mean(log(dv))),几何标准差对应原始尺度的倍数:exp(sd(log(dv))),因此误差棒上下限为几何均值 / 几何标准差和几何均值 * 几何标准差;
  • 对数轴必须避免0或负值,通过scale_y_log10(limits)设置合理下限,或过滤0值(根据需求选择)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 15:15:55