如何设置ggplot标签,使grid.arrange排列的3幅图宽度均等?
问题描述
用ggplot绘制3幅关联图表,通过gridExtra::grid.arrange()横向排列后,最左侧图表因带有较长的纵向行标签(y轴)被挤压得非常狭窄。要求3幅图的绘图区域宽度保持一致,即使整体宽度缩小以容纳行标签。此前尝试用ggtextable解决但未成功。
绘图代码
p1 <- ggplot(main.frame2, aes(x=item.true.prev, y=reorder(substring(Shorthand,5), item.true.prev), color=item.republican))+ geom_point(size=3)+ theme_forest()+ xlim(0,1)+ xlab("True Prevalence")+ylab("Item")+ scale_colour_gradient(low="blue", high="red")+ geom_stripes(odd = "#33333333", even = "#00000000")+ tidytext::scale_y_reordered() + guides(color = "none") + theme(text = element_text(size=18)) p2 <- ggplot(main.frame2, aes(x=perceived.prev, y=reorder(item.id.short, item.true.prev), color=item.republican))+ geom_point(size=3)+ theme_forest()+ xlim(0,1)+xlab("Perceived Prevalence")+ylab("")+ scale_colour_gradient(low="blue", high="red")+ geom_stripes(odd = "#33333333", even = "#00000000")+ tidytext::scale_y_reordered() + theme(axis.text.y=element_blank())+ guides(color = "none") + theme(text = element_text(size=18)) p3 <- ggplot(main.frame2, aes(x=generic.acceptance, y=reorder(item.id.short, item.true.prev), color=item.republican))+ geom_point(size=3)+ theme_forest()+ xlim(0,1)+xlab("Generic Acceptance")+ylab("")+ scale_colour_gradient(low="blue", high="red")+ geom_stripes(odd = "#33333333", even = "#00000000")+ tidytext::scale_y_reordered() + guides(color = "none")+ theme(axis.text.y=element_blank(), axis.ticks.y=element_blank())+ theme(text = element_text(size=18)) gridExtra::grid.arrange(p1,p2, p3, nrow=1)
数据样例
item.id.short Shorthand perceived.prev item.true.prev generic.acceptance <dbl> <chr> <dbl> <dbl> <dbl> 1 22 "(D) Liberal identity " 0.0755 0.07 0.0288 2 42 "(R) Conservative identity " 0.0935 0.13 0.0336 3 62 "(R) Prayer in schools" 0.132 0.18 0.0935 4 40 "(R) Require Lord's Prayer" 0.139 0.42 0.0959 5 28 "(D) Decrease police" 0.140 0.11 0.101 6 64 "(R) US as Christian nation" 0.141 0.06 0.0911 7 52 "(R) Ban trans soldiers" 0.142 0.11 0.0671 8 55 "(R) Withdraw Paris Deal" 0.154 0.11 0.0839 9 56 "(R) Build southern wall" 0.154 0.13 0.0839 10 60 "(R) Eliminate gun permits" 0.156 0.17 0.0983
解决方案
方法1:调整grid.arrange()的宽度分配
通过widths参数手动分配各图的总宽度,给左侧带标签的p1额外预留标签空间,确保三个图的绘图区域宽度一致:
# 假设绘图区域基础宽度为1单位,p1的y轴标签需要0.8单位额外宽度 gridExtra::grid.arrange(p1, p2, p3, nrow=1, widths = grid::unit(c(1.8, 1, 1), "null"))
可根据实际标签长度调整1.8的数值,直到三个图的绘图区域视觉上等宽。
方法2:使用patchwork包实现更灵活的排列
patchwork包对多图排列的对齐和宽度控制更直观,默认优先保证绘图区域等宽,同时自动适配标签空间:
library(patchwork) # 横向排列,设置宽度比例,确保p1有足够空间放标签,同时纵向对齐 p1 + p2 + p3 + plot_layout(nrow = 1, widths = c(1.8, 1, 1), align = "v")
align = "v"参数可确保三个图的纵向轴完全对齐,提升整体美观度。
补充优化:缩短y轴标签长度
如果标签过长,可先对标签进行自动换行处理,减少所需宽度:
# 在p1的y轴映射中加入换行处理 p1 <- ggplot(main.frame2, aes(x=item.true.prev, y=reorder(stringr::str_wrap(substring(Shorthand,5), width = 15), item.true.prev), color=item.republican))+ geom_point(size=3)+ theme_forest()+ xlim(0,1)+ xlab("True Prevalence")+ylab("Item")+ scale_colour_gradient(low="blue", high="red")+ geom_stripes(odd = "#33333333", even = "#00000000")+ tidytext::scale_y_reordered() + guides(color = "none") + theme(text = element_text(size=18), axis.text.y = element_text(hjust = 1)) # 右对齐换行后的标签
调整width = 15的数值可控制每行标签的字符数,让标签显示更紧凑。
内容的提问来源于stack exchange,提问作者eric andre the gian
相关产品推荐
相关产品推荐

