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

如何在ggplot2 facet grid中设置差异化x轴起始刻度?

如何用ggplot实现截断X轴的并排条形图

问题描述

想要展示两个并排条形图,说明截断X轴如何误导观众对数据的感知:

  • 左侧图表X轴范围为0–850 m
  • 右侧图表X轴从250 m开始
    但当前代码无法实现右侧X轴的截断,请问仅用ggplot该如何调整?

原始代码

library(ggplot2)
library(dplyr)
library(forcats)

buildings <- tribble(
  ~name,                         ~height_m,
  "Burj Khalifa",                828,
  "Tokyo Skytree",               634,
  "KVLY-TV mast",                629,
  "One World Trade Center",      541,
  "Large masts of INS Kattab.",  477,
  "Lualualei VLF transmitter",   472,
  "Petronas Twin Towers",        452,
  "432 Park Avenue",             426,
  "Ekibastuz GRES-2 Power St.",  419,
  "Dimona Radar Facility",       400,
  "Kiev TV Tower",               385,
  "Zhoushan O/H Powerline Tie",  380,
  "Gerbrandy Tower",             367,
  "TV Tower Vinnytsia",          354,
  "Millau Viaduct",              343,
  "Amazon Tall Tower",           325,
  "Lakhey Tower",                318,
  "Jinping-I Dam",               305
)

dados <- bind_rows(
  buildings %>% mutate(view = "Eixo 0–850 m"),
  buildings %>% mutate(view = "Eixo 250–850 m")
)

baseline <- tibble(
  name      = first(buildings$name),    
  height_m  = 250,
  view      = "Eixo 250–850 m"
)

ggplot(dados,
       aes(x = height_m,
           y = fct_reorder(name, height_m),
           fill = view)) +
  
  geom_col(show.legend = FALSE) + 
  facet_grid(. ~ view, scales = "free_x", space = "free_x") +
  
  scale_x_continuous(
    breaks   = seq(0, 850, 100),
    limits   = c(0, 850),   # vale para o painel cheio; o outro ignora
    position = "top"
  ) +
  
  scale_fill_manual(values = c("Eixo 0–850 m"  = "#334960",
                               "Eixo 250–850 m" = "#8B1E24")) +
  
  labs(
    x = NULL, y = NULL 
  ) +
  
  theme_minimal() +
  theme(
    panel.grid.major.y = element_blank(),
    strip.text         = element_text(face = "bold"),
    plot.title         = element_text(size = 11, face = "bold")
  )

问题分析

你忽略了两个关键点:

  • 全局设置的scale_x_continuous(limits = c(0,850))会覆盖scales="free_x"的效果,导致右侧面板无法独立设置X轴范围。
  • 未利用基准点数据扩展面板的X轴范围:左侧面板需要包含X=0的点才能显示0起始的轴,右侧面板需要包含X=250的点才能从250开始显示轴。

修改后的代码

library(ggplot2)
library(dplyr)
library(forcats)

buildings <- tribble(
  ~name,                         ~height_m,
  "Burj Khalifa",                828,
  "Tokyo Skytree",               634,
  "KVLY-TV mast",                629,
  "One World Trade Center",      541,
  "Large masts of INS Kattab.",  477,
  "Lualualei VLF transmitter",   472,
  "Petronas Twin Towers",        452,
  "432 Park Avenue",             426,
  "Ekibastuz GRES-2 Power St.",  419,
  "Dimona Radar Facility",       400,
  "Kiev TV Tower",               385,
  "Zhoushan O/H Powerline Tie",  380,
  "Gerbrandy Tower",             367,
  "TV Tower Vinnytsia",          354,
  "Millau Viaduct",              343,
  "Amazon Tall Tower",           325,
  "Lakhey Tower",                318,
  "Jinping-I Dam",               305
)

dados <- bind_rows(
  buildings %>% mutate(view = "Eixo 0–850 m"),
  buildings %>% mutate(view = "Eixo 250–850 m")
)

# 为左侧面板添加X=0的基准点,确保轴从0开始
left_baseline <- tibble(
  name      = first(buildings$name),
  height_m  = 0,
  view      = "Eixo 0–850 m"
)

# 右侧面板的基准点
baseline <- tibble(
  name      = first(buildings$name),    
  height_m  = 250,
  view      = "Eixo 250–850 m"
)

# 合并两个基准点数据
all_baselines <- bind_rows(left_baseline, baseline)

ggplot(dados,
       aes(x = height_m,
           y = fct_reorder(name, height_m),
           fill = view)) +
  # 添加隐形基准点,扩展面板X轴范围
  geom_blank(data = all_baselines) +
  geom_col(show.legend = FALSE) + 
  facet_grid(. ~ view, scales = "free_x", space = "free_x") +
  scale_x_continuous(
    breaks   = seq(0, 850, 100),
    # 移除全局limits,让scales="free_x"生效
    position = "top"
  ) +
  scale_fill_manual(values = c("Eixo 0–850 m"  = "#334960",
                               "Eixo 250–850 m" = "#8B1E24")) +
  labs(
    x = NULL, y = NULL 
  ) +
  theme_minimal() +
  theme(
    panel.grid.major.y = element_blank(),
    strip.text         = element_text(face = "bold"),
    plot.title         = element_text(size = 11, face = "bold")
  )

效果说明

  • 左侧面板:因添加了X=0的隐形点,X轴自动扩展到0–850 m,条形从0开始,真实展示高度差异。
  • 右侧面板:因添加了X=250的隐形点,X轴自动从250 m开始,条形的前250 m被截断,视觉上缩小了高度差异,达到误导观众的演示效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 01:20:54