如何在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
相关产品推荐
相关产品推荐

