ggplot修改单个分类y轴刻度标签为希腊字母表达式问题
问题背景
使用R语言ggplot2绘制geom_pointrange图形时,需要修改分类y轴的刻度标签:分类变量y的取值为a、b、c、d,其中取值为d的刻度需要渲染为希腊符号δ15D,其余a、b、c标签保持原样。
先后尝试两种方案均失败:
- 用dplyr的
pull、recode函数将d映射为字符串'expression(delta^15~D)',传入scale_y_discrete的labels参数后,坐标轴直接打印expression(delta^15~D)纯文本,没有渲染为公式 - 改用
paste0拼接上述表达式字符串传入,依旧无法正常渲染公式
测试用初始代码如下:
library(tidyverse) df = data.frame(y = c('a', 'b', 'c', 'd'), xmin = rep(-2, 4), x = rep(0, 4), xmax = rep(2, 4)) # 基础图形 df %>% ggplot(aes(y = y, x = x, xmin = xmin, xmax = xmax)) + geom_pointrange(show.legend = F) # 失败方案1 names <- df %>% pull(y)%>% recode( "d" = 'expression(delta^15~D)' ) df %>% ggplot(aes(y = y, x = x, xmin = xmin, xmax = xmax)) + geom_pointrange(show.legend = F) + scale_y_discrete(labels = names) # 失败方案2 names <- df %>% pull(y)%>% recode( "d" = paste0('expression(delta^15~D)') ) df %>% ggplot(aes(y = y, x = x, xmin = xmin, xmax = xmax)) + geom_pointrange(show.legend = F) + scale_y_discrete(labels = names)
失败原因
两种方案的核心问题一致:传入的是包裹了expression语法的普通字符串,不是R语言可识别的plotmath表达式对象。ggplot渲染轴标签时,遇到字符串会直接打印原文,只有遇到真正的表达式对象时,才会调用公式渲染引擎解析为希腊字母、上标等特殊格式。
可行解决方案
直接向scale_y_discrete的labels参数传入命名向量,将原刻度值作为名称,对应要显示的内容作为值:普通标签传字符串,需要渲染公式的标签直接传expression()对象(不要加引号包裹)。
注意plotmath语法中^表示上标,*表示前后内容无间隔拼接,~表示插入空格,要得到δ¹⁵D的效果,表达式写为delta^15*D即可。
可直接运行的正确代码:
library(tidyverse) df = data.frame(y = c('a', 'b', 'c', 'd'), xmin = rep(-2, 4), x = rep(0, 4), xmax = rep(2, 4)) df %>% ggplot(aes(y = y, x = x, xmin = xmin, xmax = xmax)) + geom_pointrange(show.legend = F) + scale_y_discrete(labels = c( "a" = "a", "b" = "b", "c" = "c", "d" = expression(delta^15*D) ))
如果分类水平较多、不想手动枚举所有标签,可以用动态匹配的方式只替换目标标签:
# 提取y的原始分类水平 y_levels <- unique(df$y) # 生成标签列表,仅替换d对应的内容 y_labels <- lapply(y_levels, function(lv){ if(lv == "d") return(expression(delta^15*D)) return(lv) }) df %>% ggplot(aes(y = y, x = x, xmin = xmin, xmax = xmax)) + geom_pointrange(show.legend = F) + scale_y_discrete(labels = y_labels)
内容的提问来源于stack exchange,提问作者jnat
相关产品推荐
相关产品推荐

