我正在尝试从文件(在我的情况下由 matplotlib 创建)中包含 PGF 图形,并将它们与 TikZ-externalizing 工作流程相结合。
首先,包含 PGF 图形的好处是,标签、图例等文本使用包含 .tex 文件的字体设置进行渲染。使用的好处tikzexternalize
是,在 tex 编译期间会创建 tikz 图形的 PDF,这样 (a) 耗时的 tikz 图形“构建”只需完成一次,并且 (b) 例如,发布者只需要查看和使用 tikz 图形的 PDF 版本(他们通常没有安装完整的 tikz 版本)。
我理解 PGF 是一个较低级别的框架,tikz 就是基于此框架构建的,这可能会导致一些问题。尽管如此,pgf-manual 似乎暗示上述过程原则上应该是可行的。正如之前所问过的(外部化 pgfpicture),但没有解决方案就被关闭了,我想发布一个 MWE 并发起讨论 :smile:
\documentclass{article}
\usepackage{filecontents}
\usepackage{tikz}
\begin{filecontents*}{img.pgf}
\begingroup%
\makeatletter%
\begin{pgfpicture}%
\pgfpathrectangle{\pgfpointorigin}{\pgfqpoint{3cm}{2cm}}%
\pgfusepath{use as bounding box, clip}%
\begin{pgfscope}%
\pgfpathmoveto{\pgfpointorigin}%
\pgfpathlineto{\pgfpoint{2cm}{2cm}}%
\pgfusepath{stroke}%
\pgftext[x=1cm,y=1cm]{\color{red}\large\selectfont 123456789}%
\end{pgfscope}%
\end{pgfpicture}%
\makeatother%
\endgroup%
\end{filecontents*}
\usetikzlibrary{external}
\tikzexternalize[mode=list and make]
\begin{document}%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
The first version is based on a simple tikz text and drawing and works OK:
\begin{figure}[h]
\centering
\begin{tikzpicture}
\draw[thick,rounded corners=8pt] (0,0) -- (2,2);
\node at (1,1){\color{red}\large\selectfont 123456789};
\end{tikzpicture}
\caption{... using tikz}
\end{figure}
\vspace{4em}
The second version uses the pgf file that was written using \texttt{filecontents}:
\begin{figure}[h]
\centering
% uncomment the tikzpicture environment for using "externalizing"
%\begin{tikzpicture}
\input{img.pgf}
%\end{tikzpicture}
\caption{... using a PGF image}
\end{figure}
\end{document}%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
将代码复制到文件中mwe.tex
,然后使用
pdflatex -shell-escape mwe.tex
make -f mwe.makefile
pdflatex -shell-escape mwe.tex
。
这创建了文件 one.pdf,对于所有进一步的编译运行,将直接包含该文件,而不是编译 tikzpicture。PDFmwe.pdf
还显示包含的 PGF 图看起来不错。但是,当您取消注释tikzpicture
第二个图的环境时,在以下过程中会出现错误make -f mwe.makefile
:
(./img.pgf
! TeX capacity exceeded, sorry [input stack size=5000].
\pgf@selectfontorig ->\pgf@selectfontorig
\nullfont
l.10 ... \pgftext[x=1cm,y=1cm]{\color{red}\large
\selectfont 123456789}%
现在,问题是如何解决这个问题——或者如何在不手动更改/替换代码或文件的情况下调整整个工作流程?谢谢!
答案1
更新后续跟进。使用 externalize 创建两个 pdf 图形。
我将分享我的设置及其结果。(使用 MiKTeX 和 Windows)
(1)FIGURES
在工作目录中创建一个子目录。
(2)添加到你的序言中
% **********************************************************
\tikzexternalize[%
up to date check={simple},
prefix=./FIGURES/]% Folder needs to be created before compiling
\tikzset{external/system call={%
pdflatex \tikzexternalcheckshellescape
-halt-on-error -shell-escape -interaction=batchmode
-jobname "\image" "\texsource"}}
% **********************************************************
(3)跑步
pdflatex.exe -synctex=1 -interaction=nonstopmode -shell-escape MWE.tex
(4)这是运行后的文件树。在我的系统中,它运行两次
pdflatex: security risk: running with elevated privileges This is pdfTeX, Version 3.141592653-2.6-1.40.22 (MiKTeX 21.3)
第一次举报
===== 'mode=convert with system call': Invoking 'pdflatex -shell-escape -halt-on-error -shell-escape -interaction=batchmode -jobname "./FIG
URES/MWE-figure0" "\def\tikzexternalrealjob{MWE}\input{MWE}"' ========
(img.tex
pdflatex: security risk: running with elevated privileges
This is pdfTeX, Version 3.141592653-2.6-1.40.22 (MiKTeX 21.3)
entering extended mode
===== 'mode=convert with system call': Invoking 'pdflatex -shell-escape -halt-on-error -shell-escape -interaction=batchmode -jobname "./FIG
URES/MWE-figure1" "\def\tikzexternalrealjob{MWE}\input{MWE}"' ========
)
第二次
===== Image './FIGURES/MWE-figure0' is up-to-date. ======
(img.tex
===== Image './FIGURES/MWE-figure1' is up-to-date. ======
)
(5)这是输出。
(6)这是文件MWE.tex
%%% File MWE.tex
% !TeX TS-program = pdflatex
\documentclass{article}
%%\usepackage{filecontents} % not needed anymore <<<<
\usepackage{tikz}
\usetikzlibrary{external}
\begin{filecontents*}[overwrite]{img}
\pgfpathrectangle{\pgfpointorigin}{\pgfqpoint{3cm}{2cm}}%
\pgfusepath{use as bounding box, clip}%
\begin{pgfscope}%
\pgfpathmoveto{\pgfpointorigin}%
\pgfpathlineto{\pgfpoint{2cm}{2cm}}%
\pgfusepath{stroke}%
\pgftext[x=1cm,y=1cm]{\color{red}\large\selectfont 123456789P}%
\end{pgfscope}%
\end{filecontents*}
% ********************************************************** added <<<<<<<<<<<<<<<<<<<<<<<
\tikzexternalize[%
up to date check={simple},
prefix=./FIGURES/]% Folder needs to be created before compiling
\tikzset{external/system call={%
pdflatex \tikzexternalcheckshellescape
-halt-on-error -shell-escape -interaction=batchmode
-jobname "\image" "\texsource"}}
% **********************************************************
\begin{document}%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
The first version is based on a simple tikz text and drawing and works OK:
\begin{figure}[h]
\centering
\begin{tikzpicture}
\draw[thick,rounded corners=8pt] (0,0) -- (2,2);
\node at (1,1){\color{red}\large\selectfont 123456789T};
\end{tikzpicture}
\caption{... using tikz}
\end{figure}
\vspace{4em}
The second version uses the pgf file that was written using \texttt{filecontents}:
\begin{figure}[h]
\centering
\begin{tikzpicture}
\input{img} % PGF file from matplotli
\end{tikzpicture}
\caption{... using a PGF image}
\end{figure}
\end{document}%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
答案2
错误是由于pgfpicture
在环境中有环境而导致tikzpicture
的。幸运的是,你可以通过定义一个节点来规避这个问题,即
\begin{tikzpicture}
\node {\input{img}};
\end{tikzpicture}
一切都应该顺利编译。您可以使用以下命令自动执行此操作、删除多余的填充并改进外部化文件名:
\newcommand{\inputpgf}[1]{%
\tikzsetnextfilename{#1}%
\begin{tikzpicture}%
\node[inner sep=0pt] {\input{#1.pgf}};
\end{tikzpicture}
}
img.pgf
然后,您可以通过导入和外部化图像\inputpgf{img}
。如果img.pgf
位于某个子目录中,您可以使用import
包来避免更改文件内的路径:
\newcommand{\importpgf}[2]{%
\tikzsetnextfilename{#1/#2}%
\begin{tikzpicture}%
\node[inner sep=0pt] {\import{#1}{#2.pgf}};
\end{tikzpicture}
}
您可以figures/img.pgf
通过 导入和外部化图像\importpgf{figures}{img}
。
请注意,Simon Dispa 的答案中的几乎所有更改都是无关紧要的。唯一相关的建议是pgfpicture
从img.tex
文件中删除环境。但这意味着编辑 matplotlib 输出,这相当繁琐,似乎并不受欢迎。