好的,咱们来聊聊 R 语言在 R Markdown 里用 `qplot` 画散点图,并且要把它们“堆”在一起显示。这事儿其实不难,关键在于理解 R Markdown 如何处理代码块和输出。
核心思路:代码块与输出管理
在 R Markdown 里,每个用 ```{r} 包裹起来的代码块,都会独立执行一次,并且生成对应的输出(比如图表、文本、表格等)。如果想把多个图“放在一起”,最直接的理解就是在一个输出区域里呈现多个图。
有几种常见的方法可以实现这个目标,咱们一个一个来拆解:
方法一:在同一个代码块里画多个图
这是最简单直接的方式。如果你想让两个散点图出现在同一个输出区域,只需要把画这两个图的代码放在同一个 ```{r} 代码块里就行。
场景举例: 我想对比两组数据的散点图,比如 x 轴都是 "x_var",但 y 轴分别是 "y_var1" 和 "y_var2"。
```r
title: "散点图堆叠示例"
output: html_document
```{r, fig.width=8, fig.height=4}
载入必要的包
library(ggplot2)
假设我们有一些数据
data < data.frame(
x_var = 1:10,
y_var1 = (1:10)^2,
y_var2 = sqrt(1:10) 5
)
第一个散点图
qplot(x = x_var, y = y_var1, data = data,
main = "散点图 1: Y = X^2",
xlab = "X轴变量", ylab = "Y轴变量1")
第二个散点图
qplot(x = x_var, y = y_var2, data = data,
main = "散点图 2: Y = sqrt(X) 5",
xlab = "X轴变量", ylab = "Y轴变量2")
```
解释一下:
````{r}`...` ```: 这是 R Markdown 的代码块标记。
`fig.width=8, fig.height=4`: 这是 R Markdown 的一个非常实用的 [chunk option](https://yihui.org/knitr/options/chunkoptions)。它用来控制 整个代码块 输出的图形的尺寸。当你在一个代码块里画了多个图,这个选项会尝试将它们按照一定的布局(通常是竖排或横排,取决于图形的数量和设置)适应到这个总的尺寸里。
`library(ggplot2)`: 确保你已经安装并加载了 `ggplot2` 包,因为 `qplot` 是它提供的一个方便的函数。
`qplot(...)`: 分别调用了两次 `qplot` 函数来创建两个独立的散点图。
渲染效果: 当你渲染这个 R Markdown 文档(比如点击 RStudio 的 "Knit" 按钮),这两个散点图会一个接一个地显示在 HTML 输出的同一个地方。默认情况下,它们会是竖直堆叠的。
方法二:使用 `par(mfrow)` 或 `layout()` 创建图形网格
如果你想更精细地控制多个图的排列方式,比如让它们横着并排显示,或者形成一个 2x2 的网格,那么你需要借助 R 的图形设备控制函数。在 R Markdown 的代码块里使用这些函数同样有效。
场景举例: 我想让上面那两个散点图横着并排显示,像这样: `[图1] [图2]`。
```r
title: "散点图并排示例"
output: html_document
```{r, fig.width=10, fig.height=5}
载入必要的包
library(ggplot2)
假设我们有一些数据 (同上)
data < data.frame(
x_var = 1:10,
y_var1 = (1:10)^2,
y_var2 = sqrt(1:10) 5
)
设置图形布局:2行1列的布局,绘制第一个图
或者更常用的:1行2列的布局,让图横着排列
par(mfrow = c(1, 2)) c(行数, 列数)
第一个散点图
qplot(x = x_var, y = y_var1, data = data,
main = "散点图 1",
xlab = "X", ylab = "Y1")
第二个散点图
qplot(x = x_var, y = y_var2, data = data,
main = "散点图 2",
xlab = "X", ylab = "Y2")
重要!绘制完后,将图形布局重置为默认的1行1列,
以免影响后续的代码块
par(mfrow = c(1, 1))
```
解释一下:
`par(mfrow = c(1, 2))`: 这是 R 的图形参数设置。`mfrow = c(1, 2)` 的意思是将图形设备划分成一个 1 行 2 列 的网格。然后接下来的图形会按顺序填充这个网格。
如果你想让它们竖着堆叠(和方法一类似),可以用 `par(mfrow = c(2, 1))`。
如果你有 4 个图,想排成 2x2,就用 `par(mfrow = c(2, 2))`。
`qplot(...)`: 同样是绘制散点图。因为我们设置了 `mfrow`,所以这两个图会被放置在 `mfrow` 定义的网格中。
`par(mfrow = c(1, 1))`: 这是一个非常重要的步骤! 在使用 `par()` 修改了图形布局后,一定要记得在代码块的最后将其恢复为默认的 `c(1, 1)`。否则,这个布局设置会影响到你文档中后续所有 R 代码块生成的图形,可能会导致意想不到的结果。
渲染效果: 这次渲染后,两个散点图会出现在同一个输出区域,并且是并排显示的。
`layout()` 函数: `layout()` 函数提供更灵活的网格布局控制,可以指定每个图形在哪个单元格出现,但对于简单的并排或堆叠,`par(mfrow)` 通常更方便。
方法三:使用 `ggplot2` 的 `gridExtra` 或 `patchwork` 包
如果你更喜欢用 `ggplot2` 的语法来组合图,那么 `gridExtra` 或更现代的 `patchwork` 包会是更好的选择。它们允许你用更“可视化”的方式来组合图形。
场景举例: 还是让两个散点图并排显示,这次用 `patchwork` 包。
```r
title: "散点图组合示例 (patchwork)"
output: html_document
```{r, fig.width=10, fig.height=5}
载入必要的包
library(ggplot2)
library(patchwork) 载入 patchwork 包
假设我们有一些数据 (同上)
data < data.frame(
x_var = 1:10,
y_var1 = (1:10)^2,
y_var2 = sqrt(1:10) 5
)
创建第一个 ggplot 对象 (qplot 是 ggplot 的一个简化接口,可以直接用 ggplot)
p1 < ggplot(data, aes(x = x_var, y = y_var1)) +
geom_point() +
labs(title = "散点图 1", x = "X", y = "Y1")
创建第二个 ggplot 对象
p2 < ggplot(data, aes(x = x_var, y = y_var2)) +
geom_point() +
labs(title = "散点图 2", x = "X", y = "Y2")
使用 patchwork 组合图形
'+' 号表示并排组合
p1 + p2
或者这样写,效果一样
(p1 | p2) '|' 也表示并排
```
解释一下:
`library(patchwork)`: 加载 `patchwork` 包。
`ggplot(...) + geom_point() + labs(...)`: 这里我们改用了更基础的 `ggplot()` 函数来创建图形对象(`p1` 和 `p2`)。`qplot` 也可以生成一个 `ggplot` 对象,但 `patchwork` 通常与 `ggplot` 对象配合得更好。你可以直接写 `qplot(...)`,然后把它赋值给一个变量,再用 `patchwork` 组合。
`p1 + p2`: 这是 `patchwork` 的核心用法。`+` 操作符会告诉 `patchwork` 将 `p1` 和 `p2` 并排 放置。
`p1 | p2`: `|` 操作符同样表示并排。`patchwork` 还支持 `p1 / p2` 来表示上下堆叠,以及更复杂的嵌套组合,例如 `(p1 | p2) / p3` 会把 `p1` 和 `p2` 放在上面并排,`p3` 放在下面。
渲染效果: 这次你会看到两个散点图并排显示在同一个输出区域。
选择哪种方法?
方法一 (同一个代码块): 最简单,适合不需要精细控制布局,只要图能挨着出现就行。
方法二 (`par(mfrow)`): 适合需要灵活控制网格布局(并排、堆叠、多行多列),但要注意重置 `par()` 设置。这是 R 本身的图形系统能力,非常基础可靠。
方法三 (`patchwork` 等): 最“现代化”和灵活,尤其适合你已经在使用 `ggplot2` 的语法,并且需要对图形组合进行复杂控制时。它提供了一种更符合直觉的图形组合方式。
几点额外的小提示,让你的图更专业:
1. 统一的 `fig.width` 和 `fig.height`: 在 R Markdown 的 `chunk options` 中设置代码块的总尺寸,这样可以更好地控制整体输出的比例。
2. 设置 `fig.show = "hold"`: 如果你在一个代码块里画了很多图,并且想让它们全部生成完,然后在代码块结束后一次性输出,可以使用 `fig.show = "hold"`。这个选项会将所有图形“持有”起来,直到代码块结束才一起显示。
```r
```{r, fig.width=10, fig.height=5, fig.show="hold"}
... 图1代码 ...
... 图2代码 ...
```
3. 标题和标签: 确保你的每个图都有清晰的标题 (`main` 或 `labs(title = ...)`), x 轴标签 (`xlab` 或 `labs(x = ...)`), 和 y 轴标签 (`ylab` 或 `labs(y = ...)`), 这样别人一看就知道是什么数据。
4. 数据准备: 在 R Markdown 的开头,通常会有一个代码块来加载数据和必要的 R 包。确保数据在生成图的代码块之前就已经可用。
掌握了这几种方法,你就可以灵活地在 R Markdown 里组合使用 `qplot` 画出的散点图了。关键在于理解 R Markdown 的代码块如何生成输出,以及 R 本身或 `ggplot2` 生态提供的图形组合工具。