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

如何将ggplot2图例设置为按行优先的填充排列方式?

ggplot2图例排版优化问题

我用ggplot2绘制的图表图例包含多个短标签和一个长标签,当前按列优先填充排列导致排版比例失调,希望改为行优先填充,实现以下两种布局之一:

布局一

Strongly disagree | Disagree | Slightly disagree |

Slightly agree | Agree | Strongly agree |

No opportunities to observe/Prefer not to say/I dont know

布局二

Strongly disagree | Disagree | Slightly disagree | Slightly agree | Agree | Strongly agree |

No opportunities to observe/Prefer not to say/I dont know


原图表代码

temp_chart <- ggplot(data=dat_chart, aes(x=category, y=percentage, group=question, fill = factor(answer, levels = bar_order1))) +
      geom_bar(stat = "identity", position = "stack") +
      scale_x_discrete(limits=rev, labels = wrap_format(25)) +
      scale_y_continuous(labels = function(x) paste0(x, "%")) +
      scale_fill_manual(labels = ~ stringr::str_wrap(.x, width = 20), values = culture_col1) +
      geom_vline(xintercept = (0:10)+0.5) +
      coord_flip() +
      facet_wrap(~question, ncol = 1) +
      guides(fill = guide_legend(nrow = 3, ncol = 3)) +
      theme_minimal() +
      theme(strip.text = element_text(hjust = 0),
            axis.title.x=element_blank(),
            axis.title.y=element_blank(),
            legend.title=element_blank(),
            legend.position="bottom",
            panel.grid.minor = element_blank(),
            panel.grid.major = element_blank(),
            panel.border = element_rect(color = "black", fill = NA, size = 2),
            panel.spacing = unit(0.75, "lines"))

简化数据

dput(dat_chart)
structure(list(question = c("1. Question1", 
"1. Question1", "1. Question1", 
"1. Question1", "1. Question1", 
"1. Question1", "1. Question1", 
"1. Question1", "1. Question1", 
"1. Question1", "1. Question1", 
"1. Question1", "1. Question1", 
"1. Question1", "1. Question1", 
"1. Question1", "1. Question1", 
"1. Question1", "1. Question1", 
"1. Question1", "1. Question1"
), percentage = c(3.35731414868106, 4.55635491606715, 5.03597122302158, 
13.189448441247, 47.242206235012, 26.378896882494, 0.239808153477218, 
0, 7.69230769230769, 11.5384615384615, 26.9230769230769, 30.7692307692308, 
23.0769230769231, 0, 2.02020202020202, 7.07070707070707, 13.1313131313131, 
20.2020202020202, 32.3232323232323, 25.2525252525253, 0), category = c("a", 
"a", "a", "a", "a", "a", "a", "a", 
"b", "b", "b", "b", "b", "b", "c", 
"c", "c", 
"c", "c", 
"c", "c"
), answer = c("Strongly disagree", "Disagree", "Slightly disagree", 
"Slightly agree", "Agree", "Strongly agree", "No opportunities to observe/Prefer not to say/I dont know", 
"Strongly disagree", "Disagree", "Slightly disagree", "Slightly agree", 
"Agree", "Strongly agree", "No opportunities to observe/Prefer not to say/I dont know", 
"Strongly disagree", "Disagree", "Slightly disagree", "Slightly agree", 
"Agree", "Strongly agree", "No opportunities to observe/Prefer not to say/I dont know"
)), row.names = c(NA, -21L), class = c("tbl_df", "tbl", "data.frame"
))

解决方法

ggplot2的guide_legend默认是列优先排列(byrow = FALSE),只需将该参数改为TRUE即可切换为行优先,再配合nrow和ncol参数就能实现目标布局:

实现布局一

修改guides代码段:

guides(fill = guide_legend(nrow = 3, ncol = 3, byrow = TRUE))

7个标签会按行填充:前两行各3个短标签,第三行单独放长标签。

实现布局二

调整行列数,让第一行容纳所有短标签:

guides(fill = guide_legend(nrow = 2, ncol = 7, byrow = TRUE))

设置ncol=7后,第一行会填满6个短标签,第二行单独显示长标签。

如果长标签的自动换行影响排版,可调整scale_fill_manual中str_wrap的width参数,或者直接移除str_wrap让标签完整显示。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 14:55:55