Folio Writer

自动重新生成的插图:
用 Quarto、Python 与 R 动态绘图

手稿中最危险的插图,是三个修订版之前手工做的那张。分析变了而 PNG 没变,论文就在悄悄说谎。解决办法:把代码放进手稿,让每次编译都根据数据重新生成图——Quarto 负责执行,Folio Writer 负责编排。

一个代码块说清思路

在 Folio Writer 文稿的任意位置,写一个可执行代码单元,而不是粘贴图片:

```{python}
#| label: fig-eos
#| fig-cap: "Third-order Birch–Murnaghan fit to the P–V data."
import pandas as pd, matplotlib.pyplot as plt
d = pd.read_csv("Research/pv-data.csv")
plt.plot(d.V, d.P, "o"); plt.plot(d.V, fit(d.V))
plt.xlabel("V (ų)"); plt.ylabel("P (GPa)")
```

以渲染器 = Quarto 编译,代码单元就会运行:读取 CSV,绘制拟合曲线,完成的插图落入 PDF——或 Word 文件、HTML——带编号、带题注,并像其他插图一样用 @fig-eos 引用。R 的用法完全相同:

一个 {python} 代码单元及其执行后的插图,实时显示在预览中。
一个 {python} 代码单元及其执行后的插图,实时显示在预览中。
```{r}
#| label: fig-spectra
#| fig-cap: "Raman spectra by pressure step."
library(ggplot2)
ggplot(read.csv("Research/spectra.csv"),
       aes(shift, intensity, color = factor(P))) + geom_line()
```

更新数据文件,重新编译,每张插图都是最新的。没有导出步骤,不用再问“图 3 是哪个脚本生成的?”,也没有过时的图——手稿本身就是流水线。

同一部手稿也能说 R——knitr 引擎、echo: false、带编号的插图。
同一部手稿也能说 R——knitr 引擎、echo: false、带编号的插图。

设置

  1. 安装 Quarto(quarto.org,或 brew install quarto)以及免费的 Folio Helper,它让运行在沙盒中的 App Store 应用能够调用你本地的工具链。
  2. Python 代码单元:你需要一个装有 Jupyter 的 Python(pip install jupyter matplotlib pandas)。Folio Writer 会自动让 Quarto 指向支持 Jupyter 的解释器,因此代码单元会在真正能运行它们的 Python 中执行——而不是 PATH 上碰巧排在第一位的那个 python3。
  3. R 代码单元:安装 R 以及 knitr 和 rmarkdown——即 Quarto 的标准 R 引擎。
  4. 把数据和分析脚本放在项目的 Research 文件夹中,这样整条流水线都会随手稿一起移动(和同步)。
档位说明:执行代码单元属于一次性 Pro 解锁的一部分,与编译一样(含 7 天完整试用)。编写代码单元,以及不执行代码的普通 Quarto 渲染,都不需要 Pro。
代码在哪里执行:实时预览在设计上始终保持即时——它排版文本和公式,但不运行代码。代码单元在编译时执行,即 Quarto 渲染缝合后的手稿时。想快速看一眼某张插图,只编译你正在写的那一节即可(范围 ▸ 所选文稿)。

对手稿重要的代码单元选项

Quarto 代码单元选项以 #| 注释行的形式随附。以下五个几乎覆盖了手稿的所有需求:

```{python}
#| label: fig-eos          # cite it as @fig-eos
#| fig-cap: "Compression curve with third-order fit."
#| echo: false             # figure in the paper, code not
#| fig-width: 6.5          # inches, match the journal column
#| warning: false          # keep library chatter out of the PDF
...
```

如果整部手稿都不应打印任何代码,可以在元数据文稿中统一设置一次,而不必逐个代码单元设置:

execute:
  echo: false
  warning: false
分析很慢?给耗时的代码单元加上 #| cache: true——Quarto 只会在该单元的代码改变时重新运行它,因此修改文字后重新编译不会重新拟合你的模型。
真实工作流:从 Research 中的 .xlsx 读取 P–V 数据,进行 Birch–Murnaghan 拟合,在编译时加注并编号。
真实工作流:从 Research 中的 .xlsx 读取 P–V 数据,进行 Birch–Murnaghan 拟合,在编译时加注并编号。

如果代码单元不运行

三个原因几乎涵盖所有情况。渲染器不对:只有当编译面板的渲染器为 Quarto 时代码才会执行——在 pandoc 或 Typst 下,代码单元会作为普通代码块原样输出(这是有意设计:这些流水线从不执行任何东西)。缺少引擎:编译 ▸ 设置外部工具… 会检查你的工具链;Python 代码单元需要解释器上装有 Jupyter(pip install jupyter),R 则需要 knitr + rmarkdown。路径假设:代码单元以项目为工作目录运行,所以要以 Research/pv-data.csv 的形式读取数据,而不是用你另一台电脑上的绝对路径——让路径相对于项目,也正是让合著者能够重现手稿的关键。

想静态时静态,需要动态时动态

可执行代码单元与普通插图可以共存。照片或手绘示意图仍然是普通的 Markdown 图片;由数据得出的图则变成代码单元。Folio Writer 的手稿检查甚至会留意静态插图——标出比绘制它的脚本更旧的插图——所以无论插图走哪条路,都不会悄无声息地过时。

期刊级输出同样适用

由于 Quarto 渲染器与驱动期刊格式的是同一个,动态插图在出版商模板中同样可用:添加期刊扩展(AGU、Elsevier、Copernicus…),在元数据中设置 quarto-to:,编译出的投稿文件就会带上由你的实时分析生成的插图——任何人都能用一条命令,从项目中的纯文本文件重现它。

免费下载 Folio Writer → · 更多指南