PAYATHON 2026

如何在 ggplot2 的离散轴刻度标签中使用数学表达式和斜体?

数据小陈

使用 scale_x_discrete() 设置轴标签

保留 df$x 中的类别值 d13C 和 d15N,在 scale_x_discrete() 的 labels 参数中传入 expression(),即可设置 x 轴刻度标签。

在原始绘图代码末尾添加:

+ scale_x_discrete(
  breaks = c("d13C", "d15N"),
  labels = expression(
    italic(delta)^13 * C,
    italic(delta)^15 * N
  )
)

breaks 指定要显示的类别,labels 按相同顺序提供数学标签。

完整示例

如果已经执行过修改 levels(df$x) 的代码,请先重新创建原始数据,再运行下面的绘图代码:

library(ggplot2)

df <- data.frame(
  x = factor(rep(c("d13C", "d15N"), each = 10)),
  y = c(
    rnorm(5, 1, 1),
    rnorm(5, 2, 1),
    rnorm(5, 5, 1),
    rnorm(5, 3, 1)
  ),
  group = rep(c("a", "b"), each = 5, times = 2)
)

ggplot(df, aes(x = x, y = y, col = group)) +
  geom_rect(
    aes(
      xmin = as.numeric(x) - 0.5,
      xmax = as.numeric(x) + 0.5,
      ymin = -Inf,
      ymax = Inf,
      fill = x
    ),
    alpha = 0.05
  ) +
  geom_boxplot() +
  scale_fill_manual(values = c("green", "purple")) +
  scale_x_discrete(
    breaks = c("d13C", "d15N"),
    labels = expression(
      italic(delta)^13 * C,
      italic(delta)^15 * N
    )
  )

数学标签使用 R 的 plotmath 语法:

  • delta 表示希腊字母 δ。
  • italic(...) 指定斜体格式。
  • ^13 和 ^15 表示上标。
  • * 将相邻部分连接起来,渲染时不会显示乘号。

这两个标签无需额外使用 paste()。

为什么原来的尝试没有生效?

因子的 levels 是字符标签,将 expression() 赋给它们,不会让 ggplot2 自动按数学表达式绘制。可以保留类别值作为数据标识,用 scale 的 labels 参数控制显示格式。

scale_fill_manual() 控制填充映射及其图例标签。其中设置的 labels 影响背景填充对应的图例,不会修改 x 轴刻度。如果还要美化图例,需要分别设置填充 scale 和 x 轴 scale。

label_parsed 主要用于 facet 标签。这里的两个轴标签是固定的,直接使用 expression() 更清楚。如果标签来自动态生成的字符串,可以考虑在 scale_x_discrete() 中使用 scales::label_parse(),但标签文本必须符合 plotmath 语法。

斜体范围需要单独指定

示例沿用原问题的写法,仅对 delta 使用 italic(),C 和 N 保持普通字体。如果还希望元素符号显示为斜体,可以将标签改为:

labels = expression(
  italic(delta)^13 * italic(C),
  italic(delta)^15 * italic(N)
)

备注:内容仅供参考。