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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 18:03:30