为了构建复杂的tizkpictures
,我使用savebox
es 来“导入”图形的子部分。
它工作得很好,除非我想将图形的计算外部化。在这种情况下,编译成功,但我的图形中出现以下错误(橙色填充红色边框节点内应该有一个导入的绘图):
问题:tikzpictures
如何使用es实现外部化savebox
?
平均能量损失(除非你取消注释,否则效果很好\tikzexternalize
)
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{external}
% \tikzexternalize
\begin{document}
%savebox definition
\newsavebox{\myBox}
\begin{lrbox}{\myBox}
\begin{tikzpicture}
\draw (0,0) -- (1,1);
\end{tikzpicture}
\end{lrbox}
%drawing the picture
\begin{tikzpicture}
\node[draw = red, fill = orange] {\usebox{\myBox}};
\end{tikzpicture}
\end{document}
笔记:tikzexternalize 和 savebox 错误似乎是一个非常相似的问题,但建议的解决方案(“将[保存框]的定义放在\begin{document}
”之后)显然在上述 MWE 中不起作用。(同样的解决方案在pgfmathdeclarefunction 与 savebox 和 tikzexternalize: tikzpicture 进行了优化)。
savebox
编辑:当在主tikzpicture
环境中定义时,它也不起作用 。
答案1
编辑
鉴于OP需要访问嵌套图片中的坐标,我建议使用符号 1 的\scopenode
解决方案。然而,就目前情况而言,封闭节点中的任何填充都会抹去内容。
但是,您可以修改宏,将封闭节点的内容放在其封闭材质的后面。例如,
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{external,backgrounds}
\tikzexternalize
\tikzset{external/prefix=ffigurau/}
\makeatletter
\pgfdeclarelayer{scopenode}
\pgfsetlayers{background,scopenode,main}
\tikzset{%
% adapted from tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibrarybackgrounds.code.tex
on scopenode layer/.style={%
execute at begin scope={%
\pgfonlayer{scopenode}%
\let\tikz@options=\pgfutil@empty%
\tikzset{every on scopenode layer/.try,#1}%
\tikz@options%
},
execute at end scope={\endpgfonlayer}
},
}
% ateb Symbol 1: https://tex.stackexchange.com/a/362360/
\newbox\tikz@sand@box
\newcount\tikz@scope@depth
\tikz@scope@depth111\relax
\def\scopenode[#1]#2{% name=<enw>, at=<man>, anchor=<angor>
\begin{pgfinterruptboundingbox}%
\advance\tikz@scope@depth111\relax%
% process the user option
\begin{scope}[name=tempscopenodename,at={(0,0)},anchor=center,#1]%
% try to extract positioning information: name, at, anchor
\global\let\tikz@fig@name\tikz@fig@name%
\global\let\tikz@node@at\tikz@node@at%
\global\let\tikz@anchor\tikz@anchor%
\end{scope}%
\let\tikz@scopenode@name\tikz@fig@name%
\let\tikz@scopenode@at\tikz@node@at%
\let\tikz@scopenode@anchor\tikz@anchor%
% try to typeset this scope
% we only need bounding box information
% the box itself will be discard
\setbox\tikz@sand@box=\hbox{%
\begin{scope}[local bounding box=tikz@sand@box\the\tikz@scope@depth,#1]%
#2%
\end{scope}%
}%
% goodbye. haha
\setbox\tikz@sand@box=\hbox{}%
% now typeset again
\begin{scope}[local bounding box=\tikz@scopenode@name]%
% use the bounding box information to reposition the scope
\pgftransformshift{\pgfpointanchor{tikz@sand@box\the\tikz@scope@depth}{\tikz@scopenode@anchor}%
\pgf@x-\pgf@x\pgf@y-\pgf@y}%
\pgftransformshift{\tikz@scopenode@at}%
\begin{scope}[#1]%
#2
\end{scope}%
\end{scope}%
\pgfkeys{/pgf/freeze local bounding box=\tikz@scopenode@name}%
\global\let\tikz@scopenode@name@smuggle\tikz@scopenode@name%
\end{pgfinterruptboundingbox}%
% make up the bounding box
\path(\tikz@scopenode@[email protected] west)(\tikz@scopenode@[email protected] east);%
% draw something, not necessary
\begin{scope}[on scopenode layer]%
\draw[#1](\tikz@scopenode@[email protected] west)rectangle(\tikz@scopenode@[email protected] east);%
\end{scope}%
}
\makeatother
\begin{document}
\begin{tikzpicture}
\filldraw [blue] circle (5pt);
\scopenode[draw=red, fill=orange, name=bob, at={(2,2)}, anchor=south west]{%
\draw (0,0) coordinate (a) -- (1,1) coordinate (b);
}
\scopenode[draw=blue, fill=yellow, name=gog, at={(-2,-2)}, anchor=north east]{%
\draw [magenta] (1,1) coordinate (c) -- (0,0) coordinate (d);
}
\draw [->] (a) [bend right] to (c);
\draw [->] (d) [bend right] to (b);
\end{tikzpicture}
\end{document}
原始答案和解释
编译外部图像时,Ti钾Z 会忽略文档中的所有其他图片(以及“昂贵”的命令)。这旨在通过“优化”无关紧要但耗费资源的排版任务来加快编译速度。
如果您确实需要这样做,您可以随时将其关闭。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{external}
\tikzexternalize
\tikzset{%
external/prefix=ffigurau/,
external/optimize=false,
}
\begin{document}
%savebox definition
\newsavebox{\myBox}
\begin{lrbox}{\myBox}
\begin{tikzpicture}
\draw (0,0) -- (1,1);
\end{tikzpicture}
\end{lrbox}
%drawing the picture
\begin{tikzpicture}
\node[draw = red, fill = orange] {\usebox{\myBox}};
\end{tikzpicture}
\end{document}
但是,如果您有很多图片(否则您为什么要使用外部化?),每当需要编译图片时,这将大大减慢编译速度。对于每个新的或更改的图片,将编译所有图片并执行所有“昂贵”的命令。
我不明白为什么你不能这样做。此代码使用保存框,但只是为了防止图片在主文档中排版。否则,保存框将被忽略。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{external}
\tikzexternalize
\tikzset{%
external/prefix=ffigurau/,
}
\begin{document}
%savebox definition
\newsavebox{\myBox}
\tikzsetnextfilename{mybox}
\begin{lrbox}{\myBox}
\begin{tikzpicture}
\draw (0,0) -- (1,1);
\end{tikzpicture}
\end{lrbox}
%drawing the picture
\begin{tikzpicture}
\node[draw = red, fill = orange] {\includegraphics{ffigurau/mybox}};
\end{tikzpicture}
\end{document}
说您不能在这里包含图像是没有意义的,因为无论如何,当您将其外部化时,这实际上是您正在做的事情。(保存框实际上只是这样做\includegraphics{...}
,然后您\usebox{...}
,所以您也可以直接这样做\includegraphics{...}
。