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

使用ggplot实现组合图中图例位置的精细控制问题

解决双极7点Likert量表可视化图例问题

核心思路

借助ggplot2搭配patchwork包实现图形拼接,分别管控两个子图的图例位置,或合并图例至顶部区域。

可复现代码及调整说明

先构造符合场景的示例数据:

library(ggplot2)
library(patchwork)
library(dplyr)

# 生成7点Likert量表模拟数据
set.seed(123)
likert_data <- tibble(
  item = rep(paste0("Item ", 1:5), each=7),
  response = rep(c("Strongly Disagree", "Disagree", "Slightly Disagree", 
                   "Neutral", "Slightly Agree", "Agree", "Strongly Agree"), 5),
  count = sample(10:50, 35, replace=TRUE)
)

# 拆分非中性与中性数据集
non_neutral <- likert_data %>% filter(response != "Neutral")
neutral <- likert_data %>% filter(response == "Neutral")

方案1:分图单独放置图例(最优方案)

分别绘制两个子图,关闭默认图例,手动提取并添加自定义图例到对应位置:

# 绘制非中性响应图(p1)
p1 <- ggplot(non_neutral, aes(x=item, y=count, fill=response)) +
  geom_col(position="dodge") +
  labs(y="Count", title="Non-Neutral Responses") +
  theme_minimal() +
  theme(legend.position="none", # 关闭默认图例
        plot.title = element_text(hjust=0.5)) # 标题居中

# 绘制中性响应图(p2)
p2 <- ggplot(neutral, aes(x=item, y=count, fill=response)) +
  geom_col(position="dodge") +
  labs(y="Count", title="Neutral Responses") +
  theme_minimal() +
  theme(legend.position="none",
        plot.title = element_text(hjust=0.5))

# 提取非中性图例
legend_non_neutral <- get_legend(
  ggplot(non_neutral, aes(x=item, y=count, fill=response)) +
    geom_col(position="dodge") +
    theme(legend.position="top",
          legend.title = element_blank(),
          legend.justification = "center")
)

# 提取中性图例
legend_neutral <- get_legend(
  ggplot(neutral, aes(x=item, y=count, fill=response)) +
    geom_col(position="dodge") +
    theme(legend.position="top",
          legend.title = element_blank(),
          legend.justification = "center")
)

# 拼接布局:图例+对应子图,按顺序组合
final_plot <- (legend_non_neutral / p1) / (legend_neutral / p2) +
  plot_layout(heights = c(1, 5, 1, 5)) # 调整图例与绘图区域的高度比例

print(final_plot)

方案2:合并所有图例至顶部居中(退而求其次)

将两个数据集的图例合并后,放置在整个绘图区域顶部:

# 合并数据并添加分组标识
combined_data <- likert_data %>%
  mutate(group = ifelse(response == "Neutral", "Neutral", "Non-Neutral"))

# 绘制合并图,统一设置图例位置
p_combined <- ggplot(combined_data, aes(x=item, y=count, fill=response)) +
  geom_col(position="dodge") +
  facet_wrap(~group, ncol=1) +
  labs(title="Likert Scale Responses") +
  theme_minimal() +
  theme(legend.position="top",
        legend.title = element_blank(),
        legend.justification = "center",
        plot.title = element_text(hjust=0.5),
        strip.text = element_text(size=12, face="bold"))

print(p_combined)

关键调整细节

  • 用get_legend()提取独立图例,通过patchwork的/语法将图例置于对应子图上方
  • 调整plot_layout()的heights参数,避免图例被绘图区域挤压截断
  • 若图例显示仍不完整,可添加theme(legend.key.height = unit(1, "cm"), legend.key.width = unit(1.5, "cm"))调整图例元素尺寸

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 11:01:06