调整ggplot中plot.background边距,解决图表背景过大问题
解决ggplot图表边距过大及拼接间距问题
问题根源
- 误用
scale_y_discrete():prob是连续数值变量,却用了离散刻度设置,导致y轴方向生成多余空白 coord_flip()配合单个离散x类别时,ggplot默认保留了大量冗余空间- 用标题margin临时调整的方式治标不治本,未从图表布局本身解决边距问题
具体解决方案
- 替换
scale_y_discrete()为scale_y_continuous(),设置expand = c(0, 0)彻底消除y轴上下空白 - 调整x轴
expand参数,进一步压缩左右方向的冗余空间 - 使用
theme(plot.margin)精准控制整个图表的上下左右边距,替代标题的临时margin设置 - 若用cowplot拼接图表,通过
plot_grid()的rel_heights和padding参数控制图间距
修改后的完整代码
library(dplyr) library(ggplot2) # Data win_prob <- structure(list(winner = c("draw", "team_a", "team_b"), prob = c(0.1374, 0.8412, 0.0214), team_name = c("Draw", "BYU", "Stanford")), row.names = c(NA, -3L), class = "data.frame") # Plot p1 <- win_prob |> mutate(dummy = "dummy") |> ggplot(aes(x = dummy, y = prob, fill = factor(winner, levels=c("team_b", "draw", "team_a")))) + geom_col(width = 0.02, alpha = 0.50) + geom_text(aes(label = paste0(round(prob*100, 0), "%")), position = position_stack(vjust = 0.5)) + scale_fill_manual(values = c("#8C1515", "grey", "#002E5D")) + coord_flip() + # 修正x轴expand,压缩左右空白 scale_x_discrete(expand = c(0.01, 0)) + # 替换为连续y轴,消除上下空白 scale_y_continuous(expand = c(0, 0)) + theme( legend.position = "none", # 精准控制图表整体边距,单位为mm plot.margin = margin(t = 10, r = 20, b = 10, l = 10, unit = "mm"), plot.title = element_text(size = 40), plot.subtitle = element_text(size = 28) ) + annotate("text", x = 1.02, y = 0.0, hjust = 0, label = win_prob$team_name[2], size = 8) + annotate("text", x = 1.02, y = 1.0, hjust = 1, label = win_prob$team_name[3], size = 8) + annotate("text", x = 1.02, y = 0.5, hjust = 0.5, label = "Draw", size = 8) + labs(title = "BYU vs Stanford Win Probability", subtitle = "based on xG simulation") # 若用cowplot拼接示例(假设p2是第二个图表) # library(cowplot) # plot_grid(p1, p2, ncol = 1, rel_heights = c(1, 1), padding = 0.05)
补充说明
plot.margin的四个参数分别对应上、右、下、左的边距,可根据需求调整数值- 若需要保留
theme_void(),只需在theme()里补充plot.margin即可,无需保留其他主题元素 - cowplot拼接时,
padding参数控制图之间的相对间距,rel_heights可调整各图的高度比例
内容的提问来源于stack exchange,提问作者seansteele
相关产品推荐
相关产品推荐

