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

如何将ggplot组合图的图例固定在绘图窗口顶部居中?

问题:将冲积图的图例置于绘图窗口顶部居中位置

当前使用ggplot2结合patchwork绘制冲积图时,尝试通过theme(legend.position="top")将图例放在绘图窗口顶部居中,但未生效。现需调整代码实现该需求。

原始代码

library(ggplot2)
library(ggnewscale)
library(cowplot)
library(ggalluvial)
library(patchwork)

data = 
structure(list(grp1 = c("X", "X", "X", "X", "Y", "Y", "Y", "Y"
), grp2 = c("A", "B", "C", "D", "A", "B", "C", "D"), val = c(1, 
2, 3, 4, 3, 4, 5, 6)), row.names = c(NA, -8L), class = "data.frame")

col_define = c('red', 'orange', 'blue', 'lightblue')
names(col_define) = c('A', 'B', 'C', 'D')

p <- ggplot(data, aes(x = grp1, group = grp2, y = val)) +
  geom_col(aes(fill = grp2)) +
  scale_fill_manual(values = col_define, breaks = c("A", "B"), name = "1") +
  new_scale_fill() +
  geom_col(aes(fill = grp2)) +
  scale_fill_manual(values = col_define, breaks = c("C", "D"), name = "2") +
  #guides(fill=guide_legend(order = 1, ncol = 2)) + 
  theme(legend.position="top", legend.direction = 'vertical')

p_legend <- cowplot::get_legend(p)

ggplot(data,
       aes(x = grp1, stratum = grp2, alluvium = grp2,
           y = val,
           fill = grp2)) +
  geom_flow(aes(fill = grp2), alpha = .3) +
  geom_stratum(aes(color = grp2), alpha = .9) +
  scale_fill_manual(values = col_define, breaks = names(col_define), aesthetics = c("color", "fill")) +
  guides(color = "none", fill = "none") +
  p_legend +
  theme(legend.position="top") +
  plot_layout(widths = c(50, 1))

解决方案

问题出在当前采用左右拼接(主图+图例)的布局方式,theme(legend.position)无法作用于拼接后的整体。需要改为上下布局,将图例放在顶部,主图置于下方,具体修改如下:

修改后的完整代码

library(ggplot2)
library(ggnewscale)
library(cowplot)
library(ggalluvial)
library(patchwork)

data = 
structure(list(grp1 = c("X", "X", "X", "X", "Y", "Y", "Y", "Y"
), grp2 = c("A", "B", "C", "D", "A", "B", "C", "D"), val = c(1, 
2, 3, 4, 3, 4, 5, 6)), row.names = c(NA, -8L), class = "data.frame")

col_define = c('red', 'orange', 'blue', 'lightblue')
names(col_define) = c('A', 'B', 'C', 'D')

# 提取分组后的图例,设置图例自身居中
p <- ggplot(data, aes(x = grp1, group = grp2, y = val)) +
  geom_col(aes(fill = grp2)) +
  scale_fill_manual(values = col_define, breaks = c("A", "B"), name = "1") +
  new_scale_fill() +
  geom_col(aes(fill = grp2)) +
  scale_fill_manual(values = col_define, breaks = c("C", "D"), name = "2") +
  theme(legend.position="top", legend.direction = 'vertical', 
        legend.justification = "center")

p_legend <- cowplot::get_legend(p)

# 绘制主冲积图,调整顶部边距避免与图例重叠
main_plot <- ggplot(data,
       aes(x = grp1, stratum = grp2, alluvium = grp2,
           y = val,
           fill = grp2)) +
  geom_flow(aes(fill = grp2), alpha = .3) +
  geom_stratum(aes(color = grp2), alpha = .9) +
  scale_fill_manual(values = col_define, breaks = names(col_define), aesthetics = c("color", "fill")) +
  guides(color = "none", fill = "none") +
  theme(plot.margin = margin(t = 0, r = 10, b = 10, l = 10))

# 上下布局组合:图例在上,主图在下,调整高度比例
p_legend / main_plot +
  plot_layout(heights = c(1, 10))

关键修改点

  1. 给提取图例的p图添加legend.justification = "center",确保图例自身居中;
  2. 将主图和图例的组合方式从左右拼接改为上下拼接(用/运算符);
  3. 通过plot_layout(heights = c(1, 10))调整图例与主图的高度占比,避免图例过大;
  4. 给主图添加plot.margin,消除图例与主图之间的多余空白。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 11:05:21