图表
Quarto 包含许多功能,旨在使图表和子图表的使用更加简便,同时也便于布局包含多个图表、表格或其他内容的面板。
图表基础
在 Pandoc Markdown 中,每当一个带有标题的图像独自出现在段落中时,就会创建一个图表。例如:
![大象](elephant.png)
这在不同输出类型中会呈现如下效果:
HTML | Word | |
---|---|---|
请注意,对于 LaTeX / PDF 输出,图表会自动编号(你可以使用交叉引用在其他格式中安排图表编号)。
图表尺寸
默认情况下,图表会以其实际尺寸显示(受限于其渲染的页面宽度约束)。你可以通过为图表添加 width
和 height
属性来改变显示尺寸。例如:
![大象](elephant.png){width=300}
请注意,如果仅指定 width
,则 height
会自动计算。如果你需要修改默认行为,只需添加一个显式的 height
属性。
width
和 height
的默认单位是像素。你也可以使用百分比或常规测量单位如英寸或毫米来指定尺寸。例如:
![大象](elephant.png){width=80%}
![大象](elephant.png){width=4in}
链接图表
在 Quarto 渲染时,你可以将图表嵌入链接中,它仍会在输出中被视为带有标题的图表。例如:
[![大象](elephant.png)](https://en.wikipedia.org/wiki/Elephant)
图表对齐
图表默认居中对齐。为图像添加 fig-align
属性以使用不同的对齐方式。例如:
![大象](elephant.png){fig-align="left"}
请注意,图表标题默认左对齐以适应较长的标题文本(居中对齐时看起来很奇怪)。
替代文本
你可以通过为图像添加 fig-alt
属性来为图表添加替代文本。例如,以下 Markdown…
![](elephant.png){fig-alt="一只大象的画作。"}
…会生成带有相应 alt 标签的以下 HTML:
<img src="elephant.png" alt="一只大象的画作。">
请注意,图表标题、标题和替代文本可以各不相同。例如,以下代码…
![大象](elephant.png "标题:一只大象"){fig-alt="一只大象的画作。"}
…会生成以下 HTML:
<img src="elephant.png" title="标题:一只大象" alt="一只大象的画作。">
要渲染标题而不是替代文本,可以按照Pandoc 文档中的详细说明,在行尾添加反斜杠:
![一只大象的画作。](elephant.png)\
多格式图表
你可以编写 Markdown,根据目标输出格式提供不同的图像文件格式。为此,只需省略扩展名,例如:
![](elephant)
默认情况下,这将查找 elephant.png
,但如果你渲染为 PDF,则会查找 elephant.pdf
。你可以使用 default-image-extension
选项自定义此行为。例如:
format:
html:
default-image-extension: svg
pdf:
default-image-extension: tex
灯箱图表
在 HTML 输出格式中,你可以为图像添加灯箱样式和行为,以便读者点击查看图像的更大版本。例如,以下图像是灯箱处理过的(点击图像查看灯箱效果):
可以通过为图像添加类 .lightbox
来添加灯箱处理:
![一只大象](elephant.png){.lightbox}
有关更多详细信息和其他启用和禁用灯箱处理的方法,请参阅灯箱图表。
应用多个参数
要结合上述方法,请用空格分隔参数,例如:
![](elephant.png){fig-alt="一只大象的画作。" fig-align="left" width=20%}
你可以通过为图表添加带有 fig-
前缀的 ID 来进行交叉引用,然后使用 @
前缀来引用该图表。例如:
![一只大象](elephant.png){#fig-elephant}
这一点通过 @fig-elephant 可以很好地说明。
对于由可执行代码单元格生成的图表,请包含一个带有 fig-
前缀的 label
,以便能够交叉引用它们。例如:
关于折线图的演示,请参见 @fig-line-plot。
```{python}
#| label: fig-line-plot
#| fig-cap: "一条折线图"
import matplotlib.pyplot as plt
plt.plot([1,23,2,4])
plt.show()
```
为了让一个图表能够被交叉引用,其标签必须以 fig-
前缀开头。
更多详情请参阅交叉引用文章。
子图表
如果你有一组多个图表,可以将它们放在一个图表 div 中。例如:
::: {#fig-elephants layout-ncol=2}
![Surus](surus.png){#fig-surus}
![Hanno](hanno.png){#fig-hanno}
著名的大象 :::
同样,最后一个段落提供主标题,而各个图表带有子标题。以下是渲染为 HTML 时的效果:
请注意,图表之间的空行(以及最后一个图表和标题之间的空行)是必需的(这表明这些图像是属于它们自己的段落,而不是同一段落中的多个图像)。
还要注意,我们也使用了 layout-ncol
属性来指定一个两列布局。下一节将深入探讨自定义图表布局。
图表面板
在上文中,我们展示了如何布局带有子标题和主标题的两个并排图表。你可能不需要标题/子标题的处理,或者你可能想要使用多行图表。所有这些变体都是可能的。
要布局两个带有独立标题的图表(并且没有主标题),只需去掉 #fig
标识符和底部的标题:
::: {layout-ncol=2}![Surus](surus.png)
![Hanno](hanno.png)
:::
你也可以完全去掉标题:
::: {layout-ncol=2}![](surus.png)
![](hanno.png)
:::
多行
如果你有超过两个图像,可能希望将它们分布在多行中。你可以使用 layout-nrow
属性来实现这一点。例如:
::: {layout-nrow=2}![Surus](surus.png)
![Hanno](hanno.png)
![Abdul Abbas](abdul-abbas.png)
![Lin Wang](lin-wang.png)
:::
更复杂的图表排列(例如,不同列布局的行)也是可能的。更多详情请参阅下面的自定义布局部分。
图表 Div
你可以将任何你想作为图表的 Markdown 内容包含在带有 #fig-
前缀标识符的 Pandoc div 块中。例如,这里我们创建了一个包含嵌入 iframe 的图表:
::: {#fig-elephant}
<iframe width="560" height="315" src="https://www.youtube.com/embed/SNggmeilXDQ"></iframe>
大象 :::
请注意,div 块中的最后一个段落被用作图表标题。
LaTeX 图表
本节描述一些特定于 LaTeX 输出的图表处理选项。
需要注意的一个非常重要的事情是,使用下面描述的 fig-env
和 fig-pos
选项将触发 LaTeX 浮动环境的创建(最常见的是 \begin{figure}
)。根据 LaTeX 生成的位置(例如,在另一个 \begin{figure}
内部),这可能会产生无效的 LaTeX。为了安全起见,这些属性通常只应在文档的最顶层图像中使用。
环境
有许多 LaTeX 包提供自定义的图表环境。例如,在两栏格式中,figure*
环境跨越文档的两列。你可以通过将图表环境作为图像或围栏 div 的 fig-env
属性显式传递来使用。
![大象](surus.jpg){#fig-elephant fig-env="figure*"}
::: {#fig-elephant-2 fig-env="figure*"}
![](surus.jpg)
另一只大象。
:::
图片位置
默认的 LaTeX figure
是一个浮动环境,因此它在文档中出现的具体位置将取决于其大小以及周围内容的情况。你可以使用 fig-pos
选项对这种行为进行一些控制。fig-pos
选项为 figure
环境提供了一个位置说明符。例如,以下 LaTeX 代码片段中的 ht
就是 fig-pos
:
\begin{figure}[ht]
\end{figure}
你可以在文档级别、作为可执行代码块选项或在 Markdown 中指定 fig-pos
。这里我们全部三种方式都使用了:
---
title: "我的文档"
format:
pdf:
fig-pos: 'h'
---
```{python}
#| fig-pos: 't'
```
![](figure.png){fig-pos='b'}
有关 LaTeX 图片定位的更多细节,请参阅这篇文章。
如果你的图片是由可执行代码块生成的,并且代码包含在输出中(echo: true
),那么 fig-pos
将默认设置为 H
(以尝试将其保持在生成它的代码旁边)。在所有其他情况下,除非你明确指定 fig-pos
,否则将使用默认的 LaTeX 图片位置处理。
简短标题
你可以使用 fig-scap
选项提供一个在“图片列表”中使用的简短标题。你可以在可执行代码块选项中或作为图片属性指定 fig-scap
:
```{python}
#| fig-cap: "长标题"
#| fig-scap: "短标题"
```
![长标题](figure.png){fig-scap='短标题'}
PGF/TikZ 图形
如果你正在创建 LaTeX 输出,Quarto 会自动为引用包含 PGF/TikZ 矢量图形的 .tex
文件的 Markdown 图片生成正确的 LaTeX 代码。例如,以下 Markdown 图片:
![](image1.tex)
![](image2.tex){width=80%}
将被写入 LaTeX 为:
\input{image1.tex}
\resizebox{0.8\linewidth}{!}{\input{image2.tex}}
如上所示,width
和 height
的百分比会自动转换为按 \linewidth
缩放。或者,你可以为 \resizebox
的 width
和 height
参数指定自定义的 LaTeX。
标题位置
默认情况下,图片标题位于图片下方。在 HTML 和 PDF 格式中,你可以使用 fig-cap-location
选项修改此行为。例如:
---
fig-cap-location: top
---
请注意,此选项在顶层指定,以便它可以被 PDF 和 HTML 格式共享。如果你只针对单一格式,可以将其与其他特定于格式的选项放在一起。
标题位置的有效值包括:
值 | 描述 |
---|---|
top |
将标题置于图片上方。 |
bottom |
将标题置于图片下方。 |
margin |
将标题置于页边距中。 |
有关在页边距中放置标题的更多细节,请参阅文章布局。
自定义布局
上面的示例使用了 layout-ncol
或 layout-nrow
属性来创建所有列大小相等的简单布局。layout
属性可以创建更复杂的布局。
例如,这定义了一个布局,第一行有两个大小相等的图片,然后另一张图片占据了整个第二行:
[1,1], [1]]"}
::: {layout="[![Surus](surus.png)
![Hanno](hanno.png)
![Lin Wang](lin-wang.png)
:::
layout
属性是一个二维数组,其中第一个维度定义行,第二个维度定义列。在这种情况下,"layout="[[1,1], [1]]"
翻译为:创建两行,第一行有两个大小相等的列,第二行有一个单独的列。
请注意,行中的数字是任意的,不需要加起来达到特定总数。因此,你可以使用最自然的方案。例如,这里我们定义了占据行不同百分比宽度的列:
[70,30], [100]]"}
::: {layout="[![Surus](surus.png)
![Hanno](hanno.png)
![Lin Wang](lin-wang.png)
:::
你也可以使用负值在元素之间创建空间。例如:
[40,-20,40], [100]]"}
::: {layout="[![Surus](surus.png)
![Hanno](hanno.png)
![Lin Wang](lin-wang.png)
:::
垂直对齐
如果你有一个包含不同高度图片的布局,你可以使用 layout-valign
属性来控制它们的垂直对齐方式。一个简单的例子:
[15,-2,10]" layout-valign="bottom"}
::: {layout="![Surus](surus.png)
![Lin Wang](lin-wang.png)
:::
请注意,垂直对齐不仅限于图片,你还可以对包含在面板中的任何其他元素进行垂直对齐。
计算
由可执行代码块生成的图表会自动包含在你的文档中。要设置ID、标题和链接,分别使用 label
、fig-cap
和 fig-link
选项。其他属性,例如 fig-align
和 fig-alt
,可以使用同名的选项进行设置。
你可以使用文档头部的 fig-width
和 fig-height
选项来控制计算图表的默认大小。更多关于这些选项的信息,请参阅执行选项:图表选项。
布局
请注意,图表布局属性同样适用于由可执行代码块生成的图表。以下是 Jupyter 和 Knitr 的示例:
```{python}
#| layout-ncol: 2
#| fig-cap:
#| - "线图1"
#| - "线图2"
import matplotlib.pyplot as plt
plt.plot([1,23,2,4])
plt.show()
plt.plot([8,65,23,90])
plt.show()
```
```{r}
#| layout-ncol: 2
#| fig-cap:
#| - "汽车的速度和停车距离"
#| - "汞的蒸汽压作为温度的函数"
plot(cars)
plot(pressure)
```
请注意,在这些示例中,我们还使用了 fig-cap
选项为生成的每个图表添加标题。
子标题
你可以通过结合使用 fig-cap
和 fig-subcap
选项为计算输出创建子标题。当为计算输出添加标题时,你可以选择性地包含一个带有 fig-
前缀的 label
——如果你这样做,那么图表将被编号并可交叉引用。
```{python}
#| label: fig-charts
#| fig-cap: "图表"
#| fig-subcap:
#| - "第一"
#| - "第二"
#| layout-ncol: 2
import matplotlib.pyplot as plt
plt.plot([1,23,2,4])
plt.show()
plt.plot([8,65,23,90])
plt.show()
```
```{r}
#| label: fig-charts
#| fig-cap: "图表"
#| fig-subcap:
#| - "汽车"
#| - "压力"
#| layout-ncol: 2
plot(cars)
plot(pressure)
```
自定义布局
layout
选项对于 Knitr 或 Jupyter 生成的图表的工作方式相同。例如,这是一个生成 3 个图表并为它们定义自定义布局的 Rmd 代码块:
```{r}
#| layout: [[45,-10, 45], [100]]
plot(cars)
plot(pressure)
plot(mtcars)
```
块布局
尽管上面的示例说明了图表的布局,但重要的是要注意布局属性可以用于布局任何类型的块内容。例如,这里我们将两个列表并排布局:
::: {layout-ncol=2}### 列表一
- 项目A
- 项目B
- 项目C
### 列表二
- 项目X
- 项目Y
- 项目Z
:::
注意标题会自动与后面的内容块合并,因此这个markdown总共有2列用于布局。以下是一个段落与一个项目符号列表并列的示例(无标题):
::: {layout-ncol=2}- 项目 X
- 项目 Y
- 项目 Z
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur gravida eu erat et fring. Morbi congue augue vel eros ullamcorper, eget convallis tortor sagittis. Fusce sodales viverra mauris a fringilla. Donec feugiat, justo eu blandit placerat, enim dui volutpat turpis, eu dictum lectus urna eu urna. Mauris sed massa ornare, interdum ipsum a, semper massa. :::
对于更复杂的内容,使用div(:::
)将内容划分为块以便布局。例如,以下是如何将代码单元与一些文本并列,旁边放置一个图形的示例:
[ 40, 60 ]"}
:::: {layout="
::: {#first-column}```r
# 一些代码
```
一些应该在代码下方布局的文本
:::
::: {#second-column}![](elephant.png)
:::
::::
id属性(#first-column
和#second-column
)是可选的,但有助于提高可读性。