描述中的 Matplotlib tex-macro

Matplotlib tex-macro in description

我正在使用 matplotlib 生成 pgf 文件。 基于这些,我使用独立的 tex 文件,其中仅包含必要的设置和预先构建的 pgfs。 在这种情况下,在我的绘图文件中使用自定义 tex-macros 进行描述时出现错误。

这里有一个例子 pgf 生成器:

import matplotlib as mpl
mpl.use("pgf")
mpl.rcParams.update({
    "pgf.texsystem": "pdflatex",
    "pgf.preamble": [
        #r"\newcommand{\foo}{foo}",
        r"\usepackage{import}",
        r'\subimport{./}{foo.tex}'
    ]
})

import matplotlib.pyplot as plt
plt.figure(figsize=(4.5,2.5))
plt.plot(range(5))
plt.xlabel(r'\foo{}')
plt.savefig('foo.pgf')

可以在具有以下 foo.tex 文件的目录中使用:

\newcommand{\foo}{foo}

运行 这会导致以下错误:

ValueError: Error processing '\foo{}'
LaTeX Output:
! Undefined control sequence.
<argument> ....000000}{12.000000}\selectfont \foo
                                                  {}
<*> ...ze{10.000000}{12.000000}\selectfont \foo{}}

!  ==> Fatal error occurred, no output PDF file produced!
Transcript written on texput.log.

请注意,这是编译我的独立文件时 matplotlib 而不是 产生的错误。 另请注意,当 \foo 宏作为 pgf.preamble 的一部分提供时,错误会消失 (该行被注释掉)代替。 我检查了这个变体产生的 pgf ,确实它使用了 \foo{}.

我无法进一步缩小问题范围。 这是我的具体问题:

  1. 为什么 matplotlib 会调用 pdflatex? 我正在生成 pgf 输出,因此不需要 pdflatex。 (供参考:我 straced 上面的脚本确实知道正在调用 pdflatex。)
  2. 有没有办法保存 matplotlib 试图编译的临时文件? 错误引用 texput.log(当然)该文件之后不存在。
  3. 为什么我不能在另一个 tex 文件中提供的标签中使用宏?

tl;drmatplotlibpgf.preamble 中包含 tex 文件需要绝对路径。


为了以后的调试,我推荐以下pdflatex "replacement script":

#!/usr/bin/env bash
MAIN=/usr/bin/pdflatex
cat /dev/stdin | tee /some/abs/path/to/dbg.tex | "${MAIN}" "${@}"

确保将其另存为 pdflatex,确保它是可执行的,确保 /usr/bin/pdflatex 是您的实际 pdflatex 并确保在您 [=20= 中首先找到此包装器](参见which pdflatex)。 当 运行 生成器 python 时,我们将最终的 tex 输入保留在 dbg.tex 中。 这就是 (2) 的答案。

考虑到输出,我们看到:

\documentclass{minimal}
\usepackage{import}
\subimport{./}{foo.tex}

\begin{document}
text $math \mu$
\typeout{pgf_backend_query_start}
\sbox0{\sffamily\fontsize{10.000000}{12.000000}\selectfont lp}
\typeout{\the\wd0,\the\ht0,\the\dp0}
\sbox0{\sffamily\fontsize{10.000000}{12.000000}\selectfont 0}
\typeout{\the\wd0,\the\ht0,\the\dp0}
\sbox0{\sffamily\fontsize{10.000000}{12.000000}\selectfont 1}
\typeout{\the\wd0,\the\ht0,\the\dp0}
\sbox0{\sffamily\fontsize{10.000000}{12.000000}\selectfont 2}
\typeout{\the\wd0,\the\ht0,\the\dp0}
\sbox0{\sffamily\fontsize{10.000000}{12.000000}\selectfont 3}
\typeout{\the\wd0,\the\ht0,\the\dp0}
\sbox0{\sffamily\fontsize{10.000000}{12.000000}\selectfont 4}
\typeout{\the\wd0,\the\ht0,\the\dp0}
\sbox0{\sffamily\fontsize{10.000000}{12.000000}\selectfont \foo{}}
\typeout{\the\wd0,\the\ht0,\the\dp0}

我不知道那应该有什么用。 但我猜测 matplotlib 正在尝试调整它尝试编译此 "test" 文档的字体设置。 那(某种)答案 (1).

现在得出结论(事后看来很明显): matplotlib 在临时目录中编译此示例文档。 显然,此目录中没有可用的 foo.tex,因此 subimport 失败。 从那时起,显然 \foo 将不可用。

虽然不是最干净的解决方案, 这可以通过绝对路径包含 foo.tex 来解决。 工作 python 生成器最终回答 (3):

import matplotlib as mpl
import pathlib

mpl.use("pgf")
mpl.rcParams.update({
    "pgf.texsystem": "pdflatex",
    "pgf.preamble": [
        r"\usepackage{import}",
        f'\subimport{{{pathlib.Path.cwd().resolve()}/}}{{foo.tex}}']
})

import matplotlib.pyplot as plt
plt.figure(figsize=(4.5,2.5))
plt.plot(range(5))
plt.xlabel(r'\foo{}')
plt.savefig('foo.pgf')

(我使用 python3pathlib。 对于 python2,我们宁愿回到 os.getcwd。)