如何合并R基础绘图、lattice与ggplot2三种系统生成的图形?
嘿,这个问题我之前也碰到过——毕竟R里三个绘图系统各有拿手好戏,但要把它们凑到同一张图里确实得费点心思。下面给你几个实用的方案,亲测好用:
首先先把你给出的三个绘图代码优化一下(尽量不用attach(),避免环境变量混乱):
- 基础绘图箱线图:
boxplot(mpg~cyl, data = mtcars, xlab = "Number of Cylinders", ylab = "Miles per Gallon")
- Lattice的bwplot:
library(lattice) bwplot(~mpg | cyl, data = mtcars, xlab = "Number of Cylinders", ylab = "Miles per Gallon")
- ggplot2的箱线图(补全你的qplot代码):
library(ggplot2) mtcars$cyl <- as.factor(mtcars$cyl) qplot(cyl, mpg, data = mtcars, geom = "boxplot", xlab = "Number of Cylinders", ylab = "Miles per Gallon")
方法1:用gridBase桥接基础绘图与Grid系图形(最底层实现)
基础绘图用的是base graphics系统,而Lattice和ggplot2基于grid graphics,两者渲染逻辑不同,gridBase包能帮我们在两种系统间切换视口,实现混排。
示例代码(把三个图排成一行):
# 加载依赖包 library(grid) library(gridBase) library(lattice) library(ggplot2) # 预处理数据 mtcars$cyl <- as.factor(mtcars$cyl) # 设置整体布局:1行3列 layout(matrix(1:3, nrow = 1)) # 第一个图:基础绘图 par(mar = c(4, 4, 1, 1)) # 调整边距,避免重叠 boxplot(mpg~cyl, data = mtcars, xlab = "Number of Cylinders", ylab = "Miles per Gallon") # 第二个图:Lattice绘图 # 获取基础绘图的视口,切换到grid环境 vps <- baseViewports() pushViewport(vps$inner, vps$figure, vps$plot) bwplot(~mpg | cyl, data = mtcars, xlab = "Number of Cylinders", ylab = "Miles per Gallon") upViewport(3) # 退出视口 # 第三个图:ggplot2绘图 pushViewport(vps$inner, vps$figure, vps$plot) # 关键:用print()并设置newpage=FALSE,避免ggplot新开一页 print(qplot(cyl, mpg, data = mtcars, geom = "boxplot", xlab = "Number of Cylinders", ylab = "Miles per Gallon"), newpage = FALSE) upViewport(3)
方法2:用cowplot快速整合(推荐!)
cowplot包专门解决多图排列问题,支持把base/Lattice/ggplot2的图统一转换成grid对象,然后一键排列,代码最简洁。
示例代码:
library(cowplot) library(lattice) library(ggplot2) # 预处理数据 mtcars$cyl <- as.factor(mtcars$cyl) # 1. 捕获基础绘图的内容 par(mar = c(4, 4, 1, 1)) boxplot(mpg~cyl, data = mtcars, xlab = "Number of Cylinders", ylab = "Miles per Gallon") base_plot <- recordPlot() # 把当前base图记录下来 # 2. 生成Lattice和ggplot2的图对象 lattice_plot <- bwplot(~mpg | cyl, data = mtcars, xlab = "Number of Cylinders", ylab = "Miles per Gallon") ggplot_plot <- qplot(cyl, mpg, data = mtcars, geom = "boxplot", xlab = "Number of Cylinders", ylab = "Miles per Gallon") # 3. 转换为grid兼容对象并排列 base_grob <- as_grob(base_plot) # 把base图转成grob lattice_grob <- as_grob(lattice_plot) # Lattice图转grob # 排列三个图,nrow设置行数,labels加标签区分 plot_grid(base_grob, lattice_grob, ggplot_plot, nrow = 1, labels = c("Base Plot", "Lattice Plot", "ggplot2 Plot"))
方法3:用gridExtra实现排列
gridExtra也是常用的多图排列工具,和cowplot思路类似,需要手动转换base图为grid对象:
library(gridExtra) library(grid) library(lattice) library(ggplot2) # 预处理数据 mtcars$cyl <- as.factor(mtcars$cyl) # 1. 捕获并转换基础绘图 par(mar = c(4, 4, 1, 1)) boxplot(mpg~cyl, data = mtcars, xlab = "Number of Cylinders", ylab = "Miles per Gallon") base_grob <- grid.grabExpr(recordPlot()) # 捕获base图为grob # 2. 转换Lattice和ggplot2图 lattice_grob <- as_grob(bwplot(~mpg | cyl, data = mtcars, xlab = "Number of Cylinders", ylab = "Miles per Gallon")) ggplot_grob <- ggplotGrob(qplot(cyl, mpg, data = mtcars, geom = "boxplot", xlab = "Number of Cylinders", ylab = "Miles per Gallon")) # 3. 排列图形 grid.arrange(base_grob, lattice_grob, ggplot_grob, nrow = 1)
小提示:尽量避免使用attach(),直接在绘图函数里用data=参数指定数据集,能减少很多环境变量的混乱问题。
内容的提问来源于stack exchange,提问作者nalzok
相关产品推荐
相关产品推荐

