如何扩展grid对象绘图区域以容纳图例(ggplot2/grid)
问题描述
我用fhm <- ChIPpeakAnno::featureAlignedHeatmap(...)生成了特征对齐热图,接着用ggplot2::ggsave(filename = "fn.png", plot = fhm, ...)保存图片:
- 初始保存的图片中,图例被绘图区域遮挡(对应绘图:图例被热图面板遮挡的紧凑布局图)
- 增大
ggsave()的width参数后,图例能完整显示,但整个绘图被横向拉伸,所有子面板变形且字体变得极小(对应绘图:热图面板过度拉伸、字体缩小的宽幅图)
想请教:是否可以直接编辑fhm对象,在不拉伸绘图区域的前提下扩展背景区域,让图例完整显示?
附fhm(即featureheatmap)的summary输出:
> summary(featureheatmap) Length Class Mode [1,] 5 gTree list [2,] 5 gTree list [3,] 5 gTree list [4,] 5 gTree list [5,] 5 gTree list [6,] 5 gTree list [7,] 5 gTree list [8,] 5 gTree list [9,] 5 gTree list [10,] 5 gTree list [11,] 5 gTree list [12,] 5 gTree list [13,] 5 gTree list [14,] 5 gTree list [15,] 5 gTree list [16,] 5 gTree list [17,] 5 gTree list [18,] 5 gTree list [19,] 5 gTree list [20,] 5 gTree list [21,] 5 gTree list [22,] 5 gTree list [23,] 5 gTree list [24,] 5 gTree list [25,] 5 gTree list [26,] 5 gTree list > featureheatmap %>% lapply(summary) [[1]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 1 gList list childrenOrder 1 -none- character [[2]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 2 gList list childrenOrder 2 -none- character [[3]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 2 gList list childrenOrder 2 -none- character [[4]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 2 gList list childrenOrder 2 -none- character [[5]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 2 gList list childrenOrder 2 -none- character [[6]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 2 gList list childrenOrder 2 -none- character [[7]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 2 gList list childrenOrder 2 -none- character [[8]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 2 gList list childrenOrder 2 -none- character [[9]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 2 gList list childrenOrder 2 -none- character [[10]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 2 gList list childrenOrder 2 -none- character [[11]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 2 gList list childrenOrder 2 -none- character [[12]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 1 gList list childrenOrder 1 -none- character [[13]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 2 gList list childrenOrder 2 -none- character [[14]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 1 gList list childrenOrder 1 -none- character [[15]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 2 gList list childrenOrder 2 -none- character [[16]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 1 gList list childrenOrder 1 -none- character [[17]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 2 gList list childrenOrder 2 -none- character [[18]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 1 gList list childrenOrder 1 -none- character [[19]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 2 gList list childrenOrder 2 -none- character [[20]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 1 gList list childrenOrder 1 -none- character [[21]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 2 gList list childrenOrder 2 -none- character [[22]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 1 gList list childrenOrder 1 -none- character [[23]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 2 gList list childrenOrder 2 -none- character [[24]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 1 gList list childrenOrder 1 -none- character [[25]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 2 gList list childrenOrder 2 -none- character [[26]] Length Class Mode name 1 -none- character gp 0 -none- NULL vp 33 viewport list children 1 gList list childrenOrder 1 -none- character
解决方案
fhm是由grid包的gTree对象组成的列表,属于grid绘图系统元素,可以通过调整视口(viewport)实现不拉伸绘图的前提下扩展背景空间:
方法1:调整顶层视口,预留图例空间
直接修改整个绘图的顶层视口,在右侧留出空白区域容纳图例:
library(grid) # 获取顶层绘图的视口(通常是列表第一个元素) top_vp <- fhm[[1]]$vp # 缩小绘图区域宽度,左移绘图,右侧留空 top_vp$width <- unit(0.8, "npc") top_vp$x <- unit(0.4, "npc") # 更新fhm对象的视口参数 fhm[[1]]$vp <- top_vp # 保存修改后的绘图 ggsave(filename = "fn_fixed.png", plot = fhm, width = 10, height = 8)
方法2:单独调整图例的视口位置
遍历fhm列表找到图例对应的gTree元素,修改其视口位置到绘图外的空白处:
# 遍历所有gTree,定位图例元素 for(i in seq_along(fhm)){ if(grepl("legend", fhm[[i]]$name, ignore.case = TRUE)){ # 将图例移到绘图右侧,设置合适宽度 fhm[[i]]$vp$x <- unit(0.9, "npc") fhm[[i]]$vp$width <- unit(0.15, "npc") } } # 保存调整后的绘图 ggsave(filename = "fn_legend_fixed.png", plot = fhm, width = 10, height = 8)
方法3:用gridExtra重新布局绘图与图例
将绘图区域和图例拆分后,手动分配空间重新组合:
library(gridExtra) # 拆分绘图部分和图例部分(根据实际元素数量调整索引) plot_grobs <- fhm[1:(length(fhm)-1)] legend_grob <- fhm[length(fhm)] # 重新布局,绘图占80%宽度,图例占20% final_plot <- grid.arrange( arrangeGrob(grobs = plot_grobs), arrangeGrob(grobs = legend_grob), ncol = 2, widths = c(4, 1) ) # 保存布局后的绘图 ggsave(filename = "fn_rearranged.png", plot = final_plot, width = 10, height = 8)
方法4:生成绘图时直接预留边距
调用featureAlignedHeatmap时,通过plotArgs参数提前设置右侧边距:
fhm <- ChIPpeakAnno::featureAlignedHeatmap( ... # 你的原有参数 plotArgs = list(mar = c(5, 4, 4, 8) + 0.1) # 增大右侧边距,单位为lines )
内容的提问来源于stack exchange,提问作者Josh
相关产品推荐
相关产品推荐

