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

使用ggh4x的facetted_pos_scales配置分面图Y轴刻度遇问题求助

解决ggplot2+ggh4x分面图中SALARY类Y轴刻度异常问题

问题背景

需要在分面图中展示多类别数据,其中SALARY类数值远大于FT、OE、OV_SAT三类,要求后三者Y轴固定在50-100区间以方便对比。使用ggplot2结合ggh4x的facetted_pos_scales配置差异化Y轴时,SALARY分面的刻度未正常渲染。

数据集

dat <- structure(list(u_measure = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
3L, 3L, 3L, 3L), type = c("FT", "OE", "OV_SAT", "SALARY", "FT", 
"OE", "OV_SAT", "SALARY", "FT", "OE", "OV_SAT", "SALARY"), Syd_flag = c("Syd", 
"Syd", "Syd", "Syd", "Syd", "Syd", "Syd", "Syd", "MU", "MU", 
"MU", "MU"), measure = c(80L, 75L, 90L, 65000L, 80L, 65L, 70L, 
70000L, 70L, 55L, 50L, 75000L)), class = "data.frame", row.names = c(NA, 
-12L))

原代码问题

ggplot(data = dat, aes(x = reorder(u_measure, -measure), 
             y = measure, fill = Syd_flag)) +
  geom_bar(stat = "identity") +
  facet_nested(. ~ type, 
               scales = "free", 
               labeller = label_wrap_gen(width = 25, multi_line = TRUE)) +
  ggh4x::facetted_pos_scales(y  = list(
    type != "SALARY" ~ scale_y_continuous(limits = c(50,100)),
    type == "SALARY" ~ scale_y_continuous(limits = c(65000,75000))))+
  geom_text(
    aes(y = measure,
        label = format(round(measure, 0))), 
    size = 3.5, hjust = 1.5, vjust = 0.5, angle = 90) +
  theme_minimal() +
  theme(
    axis.title.x = element_blank(),
    axis.title.y = element_blank(),
    axis.text.x = element_markdown(angle = 90, size = 11,
                                   hjust = 0, vjust = 0.5),
    axis.text.y = element_blank(),
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    legend.position = "none",
    plot.background = element_rect(colour = NA)
  )

核心问题

  1. 分面条件写法错误:facetted_pos_scales中直接使用type != "SALARY"是基于整个数据集的列判断,而非针对单个分面面板,导致Y轴scale应用异常。
  2. 全局隐藏Y轴刻度:theme(axis.text.y = element_blank())隐藏了所有分面的Y轴刻度,无法验证SALARY分面的刻度是否正常生成。
  3. 文字位置不合理:geom_text的hjust=1.5导致文字超出柱子范围,影响可视化效果。

修正方案

library(ggplot2)
library(ggh4x)

ggplot(data = dat, aes(x = reorder(u_measure, -measure), 
                       y = measure, fill = Syd_flag)) +
  geom_bar(stat = "identity") +
  facet_nested(. ~ type, 
               scales = "free", 
               labeller = label_wrap_gen(width = 25, multi_line = TRUE)) +
  # 修正分面条件,用vars指定面板级判断
  ggh4x::facetted_pos_scales(y = list(
    vars(type %in% c("FT", "OE", "OV_SAT")) ~ scale_y_continuous(limits = c(50, 100)),
    vars(type == "SALARY") ~ scale_y_continuous(limits = c(65000, 75000), 
                                                breaks = seq(65000, 75000, 5000))
  )) +
  geom_text(
    aes(y = measure,
        label = format(round(measure, 0))), 
    size = 3.5, hjust = -0.1, vjust = 0.5 # 调整文字位置避免超出
  ) +
  theme_minimal() +
  theme(
    axis.title.x = element_blank(),
    axis.title.y = element_blank(),
    axis.text.x = element_markdown(angle = 90, size = 11,
                                   hjust = 1, vjust = 0.5), # 优化x轴文字对齐
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    legend.position = "none",
    plot.background = element_rect(colour = NA)
  ) +
  # 差异化主题:仅SALARY分面显示Y轴刻度
  ggh4x::facetted_themes(
    y = list(
      vars(type == "SALARY") ~ theme(axis.text.y = element_text(size = 9)),
      vars(type != "SALARY") ~ theme(axis.text.y = element_blank())
    )
  )

关键修正点

  • 分面条件修正:使用vars()包裹分面变量的条件,确保每个面板匹配对应的Y轴scale。
  • 自定义刻度:为SALARY分面添加breaks参数,手动设置刻度间隔,让刻度显示更清晰。
  • 差异化主题:通过facetted_themes实现仅SALARY分面显示Y轴刻度,其他分面保持隐藏,兼顾对比需求和刻度可读性。
  • 文字位置优化:调整geom_text的hjust参数,避免文字超出图表范围;优化x轴文字对齐方式,提升可读性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 07:25:04