R中cowplot包问题:拼接grob并导出PDF时项目符号变为椭圆
问题:cowplot拼接consort流程图导出PDF时项目符号变椭圆
使用consort包生成流程图,单独绘制显示正常,但通过cowplot拼接后导出PDF,流程图中的项目符号会变成椭圆,导出PNG则无此问题。最小复现代码如下:
library(consort) library(cowplot) library(ggplotify) # 生成流程图A participant_id <- 1:10 exclusion <- rep(NA, 10) exclusion[1:3] <- "Lost to follow-up" df <- data.frame(participant_id, exclusion) flowchart_a <- consort_plot(data = df, orders = c(participant_id = "Invited participants", exclusion = "Excluded", participant_id = "Completed the study"), side_box = c("exclusion"), cex = 0.9) # 生成流程图B rm(participant_id, exclusion, df) participant_id <- 1:10 exclusion <- rep(NA, 10) exclusion[1:2] <- "Lost to follow-up" df <- data.frame(participant_id, exclusion) flowchart_b <- consort_plot(data = df, orders = c(participant_id = "Invited participants", exclusion = "Excluded", participant_id = "Completed the study"), side_box = c("exclusion"), cex = 0.9) # 拼接并导出PDF grob1 <- as.grob(function() plot(flowchart_a)) grob2 <- as.grob(function() plot(flowchart_b)) grid <- plot_grid(grob1, NULL, grob2, rel_heights = c(1, 0.3, 1), labels = c("A", "", "B"), ncol = 1) save_plot("panel.pdf", grid, nrow = 2, ncol = 1.5)
原因分析
该问题源于consort包基于base R绘图系统生成流程图,其项目符号依赖base R的pch参数定义。当通过ggplotify::as.grob()将base绘图转为grob对象,再用cowplot::save_plot()导出PDF时,矢量格式下的符号渲染逻辑出现异常,导致圆形符号被拉伸为椭圆;而PNG是位图格式,渲染逻辑不受此影响。
解决方案
方法1:改用base R原生PDF设备保存
绕过cowplot::save_plot(),直接使用base R的pdf()设备输出拼接后的图形,避免矢量渲染异常:
# (生成流程图A、B及拼接代码同原示例) # 使用base R的pdf设备保存 pdf("panel.pdf", width = 8, height = 10) grid.draw(grid) dev.off()
方法2:自定义consort流程图的项目符号
修改consort_plot()的pch参数,使用矢量友好的Unicode圆形符号,避免拉伸问题:
# 生成流程图时指定pch为Unicode实心圆 flowchart_a <- consort_plot(data = df, orders = c(participant_id = "Invited participants", exclusion = "Excluded", participant_id = "Completed the study"), side_box = c("exclusion"), cex = 0.9, pch = "\u25CF") flowchart_b <- consort_plot(data = df, orders = c(participant_id = "Invited participants", exclusion = "Excluded", participant_id = "Completed the study"), side_box = c("exclusion"), cex = 0.9, pch = "\u25CF") # 后续拼接导出代码同原示例
方法3:使用gridGraphics更精准转换base绘图为grob
gridGraphics包提供更完整的base绘图转grob能力,替代ggplotify::as.grob():
library(gridGraphics) # 转换base绘图为grob grob1 <- grid.grabExpr(plot(flowchart_a)) grob2 <- grid.grabExpr(plot(flowchart_b)) # 后续拼接导出代码同原示例
内容的提问来源于stack exchange,提问作者vlangen
相关产品推荐
相关产品推荐

