使用ggplot2制作以零为中心的堆叠蝴蝶/龙卷风图展示Likert问卷前后数据
解决方案
先处理数据,把occasion转成带标签的因子,方便区分前后:
all.gg.data <- all.gg.data %>% mutate(occasion = factor(occasion, levels = c(1, 2), labels = c("Before", "After")))
替换你的ggplot代码,核心调整分面方式和参数,实现水平对齐的堆叠分面:
library(ggplot2) library(dplyr) library(scales) likert_viz <- ggplot(all.gg.data, aes(x = number, y = item, fill = opinion)) + geom_col(width = 0.8) + # 把过宽的条形调窄,避免重叠 geom_vline(xintercept = 50, color = "white", linewidth = 1) + # 强化中间参考线 scale_y_discrete(limits = unique(all.gg.data$item), # 固定y轴问题顺序,两个分面对齐 labels = wrap_format(50)) + scale_x_continuous(labels = percent_format(scale = 1), # 若number是小数,把scale改成100 breaks = seq(0, 100, 25)) + labs(title = "教育模块实施前后观点对比", subtitle = "Likert问卷结果", x = "百分比", y = "问题", fill = "观点") + facet_grid(. ~ occasion) + # 替代facet_wrap,实现左右水平分面且y轴完全对齐 theme_minimal() + theme( strip.text = element_text(size = 12, face = "bold"), plot.title = element_text(size = 14, face = "bold", hjust = 0.5), plot.subtitle = element_text(hjust = 0.5) ) print(likert_viz)
关键修改说明:
- 用
facet_grid(. ~ occasion)替代facet_wrap:生成左右严格对齐的分面,保证同一个问题在两个分组里的y轴位置完全一致,解决分面不对齐的核心问题。 - 固定y轴顺序:用
unique(all.gg.data$item)做刻度限制,避免数据重复导致的问题顺序混乱。 - 调整条形宽度:把原有的
width=5.0改成0.8,让条形紧凑合理,不会互相重叠。
如果想要传统“蝴蝶图”(Before在x轴左侧负方向,After在右侧正方向,同一问题在同一y位置),可以用这个版本:
# 先调整数据:把Before的数值取反 all.gg.data <- all.gg.data %>% mutate( occasion = factor(occasion, levels = c(1, 2), labels = c("Before", "After")), number = ifelse(occasion == "Before", -number, number) ) likert_butterfly <- ggplot(all.gg.data, aes(x = number, y = item, fill = opinion)) + geom_col(width = 0.8) + geom_vline(xintercept = 0, color = "black", linewidth = 1) + scale_y_discrete(limits = unique(all.gg.data$item), labels = wrap_format(50)) + scale_x_continuous(labels = function(x) paste0(abs(x), "%"), # 显示绝对值百分比 breaks = seq(-100, 100, 25)) + labs(title = "教育模块实施前后观点对比(蝴蝶图)", subtitle = "Likert问卷结果", x = "百分比", y = "问题", fill = "观点") + theme_minimal() + theme( plot.title = element_text(size = 14, face = "bold", hjust = 0.5), plot.subtitle = element_text(hjust = 0.5) ) print(likert_butterfly)
内容的提问来源于stack exchange,提问作者Nervous Optic Head
相关产品推荐
相关产品推荐

