我的情节中有一部分我想重复几次。
确切地说,我想要复制的部分是:
\draw[yscale=2.0,yshift=-3,xscale=0.1,domain=0:10] plot[id=gauss1] function{exp(-(x-5)*(x-5)/2/2/2.0)/sqrt(pi)/2};
\draw[yscale=2.0,yshift=-3,xscale=0.1,domain=5:15] plot[id=gauss2] function{exp(-(x-10)*(x-10)/2/2/2.0)/sqrt(pi)/2};
我想将这个相同的函数放在我的 tikz 矩阵的多个位置(我想在多个位置重复这两个精确的语句)
最好的方法是什么?有没有办法不复制粘贴?
我尝试将其包含在 \input{sometexfile} 中,但会导致编译错误。
答案1
为了填补@philosodad 的第一个方法,这会做你想做的事并服从干燥:
\begin{scope}[yscale=2.0,yshift=-3,xscale=0.1]
\foreach \i/\mu/\xmin/\xmax in {1/5/0/10,2/10/5/15} {
\draw[domain=\xmin:\xmax] plot[id=gauss\i] function{exp(-(x-\mu)*(x-\mu)/2/2/2.0)/sqrt(pi)/2};
}
\end{scope}
范围环境不是必需的(您可以将这些选项放在\draw
行上)但它确实使行更短。:-)
如果您想将其放在多个地方,只需将其分配到一个框中。
\usetikzlibrary{matrix}
\newsavebox{\gaussians}
\savebox{\gaussians}{
\begin{tikzpicture}
\begin{scope}[yscale=2.0,yshift=-3,xscale=0.1]
\foreach \i/\mu/\xmin/\xmax in {1/5/0/10,2/10/5/15} {
\draw[domain=\xmin:\xmax] plot[id=gauss\i] function{exp(-(x-\mu)*(x-\mu)/2/2/2.0)/sqrt(pi)/2};
}
\end{scope}
\end{tikzpicture}
}
\begin{tikzpicture}
\node[matrix of nodes] {
\usebox{\gaussians} & foo & \usebox{\gaussians} \\
bar & \usebox{\gaussians} & baz \\
};
\end{tikzpicture}
编辑:根据 Yossi 的建议,我重写了它以使用已保存的框而不是宏。
答案2
使用TiKZ 3.0 pics
可以轻松重用图像的一部分。您需要在 中声明可重用部分,并将其放置在pic
所需的位置,甚至可以在 中matrix
。
\documentclass[border=2mm,tikz]{standalone}
\tikzset{
mygauss/.pic={
\draw[yscale=2.0,yshift=-3,xscale=0.1,domain=0:10] plot[id=gauss1]
function{exp(-(x-5)*(x-5)/2/2/2.0)/sqrt(pi)/2};
\draw[yscale=2.0,yshift=-3,xscale=0.1,domain=5:15] plot[id=gauss2]
function{exp(-(x-10)*(x-10)/2/2/2.0)/sqrt(pi)/2};
}}
\begin{document}
\begin{tikzpicture}
\matrix (A) [column sep=5mm, row sep=3mm] {
\pic{mygauss}; & \pic{mygauss}; & \pic{mygauss}; \\
\pic[red]{mygauss}; & \pic{mygauss}; & \pic{mygauss}; \\
\pic{mygauss}; & \pic{mygauss}; & \pic[green,dashed]{mygauss}; \\};
\end{tikzpicture}
\end{document}
作为通常使用 gnuplot 时,我们需要使用 -shell-escape 进行编译,如 pdflatex -shell-escape myfile.tex
答案3
人们似乎在回答不同的问题……我可能错了,但我认为你在找 \savebox
?这不会让 latex 每次都重新渲染 TikZ 代码吗?我不知道你需要将这些图放入文档中多少次,但如果你要定义一个宏来执行此操作,你可以考虑将整个内容放入\savebox
:
\newsavebox{\myneatfigurethatineedalot}
\savebox{\myneatfigurethatineedalot}{
A bunch of latex code, tikz and
what-not that you need to place on every corner of every page
}
\usebox{\myneatfigurethatineedalot} %use this wherever you want it!
我认为\savebox
在这种情况下这比使用宏更好,因为 a)框中的内容是独立的(框内容的排版不依赖于文本中的位置)并且 b)渲染成本相对较高,并且通过使用,\savebox
您告诉 texengine 只需重用渲染结果,而宏会告诉它从头开始重新渲染所有内容。
答案4
PGF 手册提到了以下两个命令:
\pgfsys@defobject{⟨name⟩}{⟨lower left⟩}{⟨upper right⟩}{⟨code⟩}
声明一个对象以供稍后使用。这个想法是,该对象可以以某种方式预先缓存,然后在多次使用时更快地渲染。例如,箭头可以用这种方式定义和预渲染。参数⟨name⟩是稍后使用的名称。⟨lower left⟩和⟨upper right⟩是指定对象边界框的 pgf 点。⟨code⟩是对象的代码。代码不应该太花哨。此命令具有默认实现,不需要由驱动程序文件实现。\pgfsys@useobject{⟨name⟩}{⟨extra code⟩}
渲染先前声明的对象。第一个参数是对象的名称。第二个参数是应在渲染对象之前执行的额外代码。通常,这将是一些转换代码。此命令具有默认实现,无需由驱动程序文件实现。
不幸的是,我从来不明白它们是如何工作的,所以请将其视为一个扩展的评论或与原文相关的新问题。