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

如何在分面ggplot中镜像strip.text至另一侧并自定义标签

问题需求

我正在处理9个调查项目(q1至q9)的数据,所有项目均采用11点量表测量对陈述的同意/不同意程度,已将数据转换为长格式方便可视化。我想绘制类似ggridges的分面密度图(因ggridges灵活性不足未使用),目前已完成基础绘图,还需要实现两个需求:

  • 将分面标签(strip.text)镜像到绘图右侧
  • 将分面标签替换为对应项目的同意/不同意选项文本

当前代码

theme_set(theme_minimal())

ggplot(df, aes(x = value, y = ..count.., fill = name)) +
  geom_density(color = "transparent") +
  facet_grid(name ~ ., switch = "y") +
  scale_fill_viridis_d(direction = -1, guide = "none") + 
  labs(x="", y="") +
  xlim(-1, 13) +
  theme(panel.grid.minor = element_blank(),
        axis.text.y = element_blank(),
        strip.text.y.left = element_text(angle = 0, vjust = 0),
        strip.text.y.right = element_text(angle = 0, vjust = 0))

示例数据

structure(list(name = c("q1", "q2", "q3", "q4", "q5", "q6", "q7", 
                        "q8", "q9", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", 
                        "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q1", "q2", 
                        "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q1", "q2", "q3", "q4", 
                        "q5", "q6", "q7", "q8", "q9", "q1", "q2", "q3", "q4", "q5", "q6", 
                        "q7", "q8", "q9", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", 
                        "q9", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q1", 
                        "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q1", "q2", "q3", 
                        "q4", "q5", "q6", "q7", "q8", "q9"), 
               value = structure(c(8, 1, 3, 9, 4, 11, 3, 10, 6, 5, 1, 11, 8, 1, 7, 8, 9, 5, 4, 8, 6, 6, 
                                   8, 7, 4, 6, 5, 1, 3, 11, 9, 9, 6, 4, 10, 4, 7, 3, 5, 9, 6, 9, 
                                   6, 10, 8, 1, 3, 6, 8, 6, 11, 11, 11, 11, 3, 3, 1, 6, 9, 11, 6, 
                                   11, 8, 3, 9, 11, 1, 3, 11, 11, 3, 11, 5, 4, 11, 2, 8, 10, 6, 
                                   6, 9, 6, 10, 5, 6, 11, 10, 3, 8, 1)),
               left = c("增加社会支出", "投资气候领域", 
                        "增加对乌克兰援助", "促进移民", "更多公平与多元化", 
                        "增加对富裕家庭的援助", "更多监控以提升安全", 
                        "深化欧洲一体化", "保留口罩强制令", 
                        "增加社会支出", "投资气候领域", "增加对乌克兰援助", 
                        "促进移民", "更多公平与多元化", "增加对富裕家庭的援助", 
                        "更多监控以提升安全", "深化欧洲一体化", 
                        "保留口罩强制令", "增加社会支出", "投资气候领域", 
                        "增加对乌克兰援助", "促进移民", "更多公平与多元化", 
                        "增加对富裕家庭的援助", "更多监控以提升安全", 
                        "深化欧洲一体化", "保留口罩强制令", 
                        "增加社会支出", "投资气候领域", "增加对乌克兰援助", 
                        "促进移民", "更多公平与多元化", "增加对富裕家庭的援助", 
                        "更多监控以提升安全", "深化欧洲一体化", 
                        "保留口罩强制令", "增加社会支出", "投资气候领域", 
                        "增加对乌克兰援助", "促进移民", "更多公平与多元化", 
                        "增加对富裕家庭的援助", "更多监控以提升安全", 
                        "深化欧洲一体化", "保留口罩强制令", 
                        "增加社会支出", "投资气候领域", "增加对乌克兰援助", 
                        "促进移民", "更多公平与多元化", "增加对富裕家庭的援助", 
                        "更多监控以提升安全", "深化欧洲一体化", 
                        "保留口罩强制令", "增加社会支出", "投资气候领域", 
                        "增加对乌克兰援助", "促进移民", "更多公平与多元化", 
                        "增加对富裕家庭的援助", "更多监控以提升安全", 
                        "深化欧洲一体化", "保留口罩强制令", 
                        "增加社会支出", "投资气候领域", "增加对乌克兰援助", 
                        "促进移民", "更多公平与多元化", "增加对富裕家庭的援助", 
                        "更多监控以提升安全", "深化欧洲一体化", 
                        "保留口罩强制令", "增加社会支出", "投资气候领域", 
                        "增加对乌克兰援助", "促进移民", "更多公平与多元化", 
                        "增加对富裕家庭的援助", "更多监控以提升安全", 
                        "深化欧洲一体化", "保留口罩强制令", 
                        "增加社会支出", "投资气候领域", "增加对乌克兰援助", 
                        "促进移民", "更多公平与多元化", "增加对富裕家庭的援助", 
                        "更多监控以提升安全", "深化欧洲一体化", 
                        "保留口罩强制令"), 
               right = c("减少社会支出", 
                         "投资经济领域", "保持中立", "限制移民", 
                         "社会公平已实现", "减少对富裕家庭的援助", 
                         "减少监控以提升自由", "欧洲一体化过度", 
                         "取消口罩强制令", "减少社会支出", "投资经济领域", 
                         "保持中立", "限制移民", "社会公平已实现", "减少对富裕家庭的援助", 
                         "减少监控以提升自由", "欧洲一体化过度", "取消口罩强制令", 
                         "减少社会支出", "投资经济领域", "保持中立", 
                         "限制移民", "社会公平已实现", "减少对富裕家庭的援助", 
                         "减少监控以提升自由", "欧洲一体化过度", "取消口罩强制令", 
                         "减少社会支出", "投资经济领域", "保持中立", 
                         "限制移民", "社会公平已实现", "减少对富裕家庭的援助", 
                         "减少监控以提升自由", "欧洲一体化过度", "取消口罩强制令", 
                         "减少社会支出", "投资经济领域", "保持中立", 
                         "限制移民", "社会公平已实现", "减少对富裕家庭的援助", 
                         "减少监控以提升自由", "欧洲一体化过度", "取消口罩强制令", 
                         "减少社会支出", "投资经济领域", "保持中立", 
                         "限制移民", "社会公平已实现", "减少对富裕家庭的援助", 
                         "减少监控以提升自由", "欧洲一体化过度", "取消口罩强制令", 
                         "减少社会支出", "投资经济领域", "保持中立", 
                         "限制移民", "社会公平已实现", "减少对富裕家庭的援助", 
                         "减少监控以提升自由", "欧洲一体化过度", "取消口罩强制令", 
                         "减少社会支出", "投资经济领域", "保持中立", 
                         "限制移民", "社会公平已实现", "减少对富裕家庭的援助", 
                         "减少监控以提升自由", "欧洲一体化过度", "取消口罩强制令", 
                         "减少社会支出", "投资经济领域", "保持中立", 
                         "限制移民", "社会公平已实现", "减少对富裕家庭的援助", 
                         "减少监控以提升自由", "欧洲一体化过度", "取消口罩强制令", 
                         "减少社会支出", "投资经济领域", "保持中立", 
                         "限制移民", "社会公平已实现", "减少对富裕家庭的援助", 
                         "减少监控以提升自由", "欧洲一体化过度", "取消口罩强制令")), 
          row.names = c(NA, -90L), class = c("tbl_df", "tbl", "data.frame"))

解决方案

步骤1:预处理数据生成自定义分面标签

先提取每个项目对应的同意/不同意选项对,生成唯一的分面标签,避免重复计算:

# 提取每个项目的唯一选项对,拼接成分面标签
label_map <- df %>% 
  distinct(name, left, right) %>% 
  mutate(facet_label = paste(left, "\nvs.\n", right))

# 将标签映射合并到原数据
df <- df %>% left_join(label_map, by = c("name", "left", "right"))

步骤2:修改绘图代码实现需求

theme_set(theme_minimal())

ggplot(df, aes(x = value, y = ..count.., fill = name)) +
  geom_density(color = "transparent") +
  # 使用自定义标签分面,switch="y"将标签移至y轴外侧
  facet_grid(facet_label ~ ., switch = "y", scales = "free_y", space = "free_y") +
  scale_fill_viridis_d(direction = -1, guide = "none") + 
  labs(x = "", y = "") +
  xlim(-1, 13) +
  theme(
    panel.grid.minor = element_blank(),
    axis.text.y = element_blank(),
    # 隐藏左侧默认标签
    strip.text.y.left = element_blank(),
    # 设置右侧标签样式:水平显示、左对齐
    strip.text.y.right = element_text(angle = 0, vjust = 0.5, hjust = 0, lineheight = 1.2),
    # 将标签放在绘图区域外侧,避免遮挡
    strip.placement = "outside"
  )

关键说明

  1. 自定义分面标签:通过拼接每个项目的left(同意方向)和right(不同意方向)文本,生成带换行的对比标签,让分面直接展示调查选项。
  2. 镜像标签到右侧:利用switch="y"将分面标签移到y轴外侧,隐藏左侧标签后,仅保留并配置右侧标签的样式,配合strip.placement="outside"确保标签完整显示。

内容的提问来源于stack exchange,提问作者Dr. Fabian Habersack

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 02:52:03