使用scales::label_number()结合facetted_pos_scales()左轴标签出现NA问题
蝴蝶图左侧轴标签修改出现NA的问题解决
问题背景
原本用ggpol包的facet_share绘制蝴蝶图能正常运行,代码如下:
librarian::shelf(ggpol, tidyverse) dat <- tibble(group = rep(letters[1:5], each = 2), type = factor(paste0("type", rep(c(1:2), 5))), value = c(-50, 110, -45, 120, -40, 130, -35, 140, -30, 150)) dat %>% ggplot(aes(x = value, y = group)) + geom_col() + facet_share(~type, scales = "free", reverse_num = TRUE) + facetted_pos_scales( x = list(scale_x_continuous(limits = c(-40, -30)), scale_x_continuous(limits = c(35, 215))))
但给左侧x轴加scales::label_number(decimal.mark = ",")修改标签格式时,左侧轴出现NA值,代码如下:
dat %>% ggplot(aes(x = value, y = group)) + geom_col() + facet_share(~type, scales = "free", reverse_num = TRUE) + facetted_pos_scales( x = list(scale_x_continuous(limits = c(-40, -30), labels = label_number(decimal.mark = ",")), scale_x_continuous(limits = c(35, 215))))
另外发现,label_percent()在右侧轴正常,但在左侧轴同样失效。
问题原因
核心问题是facet_share的reverse_num = TRUE会把左侧轴的数值反转成正数显示,但标签函数接收的还是原始的负数数值。而label_number()这类函数默认会过滤掉不在设定轴范围内的数值——左侧轴limits设的是c(-40, -30),但反转后实际显示的是30到40的正数,标签函数拿到的却是-30到-40的负数,这些数值不在设定的limits里,所以被判定为无效值返回NA。
label_percent()同理,左侧轴的负数不在显示范围内,导致标签生成失败。
解决方法
只需要让标签函数先把负数转为正数,再应用格式转换即可,有两种简单实现方式:
方法一:自定义标签函数适配反转逻辑
利用匿名函数先取绝对值,再传入label_number():
dat %>% ggplot(aes(x = value, y = group)) + geom_col() + facet_share(~type, scales = "free", reverse_num = TRUE) + facetted_pos_scales( x = list(scale_x_continuous(limits = c(-40, -30), labels = function(x) scales::label_number(decimal.mark = ",")(abs(x))), scale_x_continuous(limits = c(35, 215))))
方法二:直接用scales::number()处理
直接调用number()函数处理绝对值,效果一样:
dat %>% ggplot(aes(x = value, y = group)) + geom_col() + facet_share(~type, scales = "free", reverse_num = TRUE) + facetted_pos_scales( x = list(scale_x_continuous(limits = c(-40, -30), labels = function(x) scales::number(abs(x), decimal.mark = ",")), scale_x_continuous(limits = c(35, 215))))
如果是用label_percent(),同样用取绝对值的逻辑:
# 注意这里数据value要改成小数,示例调整了数值范围 dat_percent <- dat %>% mutate(value = value/100) dat_percent %>% ggplot(aes(x = value, y = group)) + geom_col() + facet_share(~type, scales = "free", reverse_num = TRUE) + facetted_pos_scales( x = list(scale_x_continuous(limits = c(-0.4, -0.3), labels = function(x) scales::label_percent()(abs(x))), scale_x_continuous(limits = c(0.35, 0.6))))
内容的提问来源于stack exchange,提问作者r-newbie
相关产品推荐
相关产品推荐

