# Is it possible to reuse a part of a tikz image

I have a part of my plot that I want to repeat several times.

To be exact, the part I want to replicate is:

\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};


I want to place this same function in multiple places in my tikz matrix (I want to repeat this two exact statements on multiple places)

What is the best way of doing this? Is there a way to not copy-paste this?

I tried including this with \input{sometexfile} but that does give compile errors.

-

## 5 Answers

To fill in @philosodad's first way, this does what you want and obeys DRY:

\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}


The scope environment isn't required (you can put those options on the \draw line) but it does make the line shorter. :-)

If you want to put that in multiple places, just assign it to a box.

\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}


Edit: Following Yossi's suggestion, I rewrote this to use a saved box rather than a macro.

-
Maybe I was not completely clear. It is not a single draw command I want to repeat, but the two draw commands together that I want to do in multiple tikz matrix cells. I can't think of doing that with foreach. – Peter Smit Oct 26 '10 at 13:15
Answer edited... – Matthew Leingang Oct 26 '10 at 13:37
you could even define newcommand{\gaussians}{\usebox{\gaussianbox}} – Yossi Farjoun Oct 26 '10 at 21:24
I might be wrong, but it looks like it does not work when you externalize the rendering of tikz pictures in order to produce PDFs (I need it to generate html with tex4ht). The tikz picture of the savebox is saved as PDF, whereas the tikz picture that uses the savebox gets lost. – mmj Jun 16 '13 at 6:53

I think there are two ways to do this.

If you need to repeat the statements consistently enough to design a for loop, the Tikz foreach statement might be the correct move.

If you want to use basic text replacement, you should be able to define either a tikzstyle or a TeX macro to replace the longer statement.

-
Perhaps supplement your answer with an example: \necommand{\repeatgraph}{\draw[yscale etc... – Seamus Oct 26 '10 at 11:57

People seem to be answering a different question...I may be wrong but I think you are looking for \savebox? Would this not save latex from re-rendering the TikZ code every time? I don't know how many times you need to put those plots in your document, but if you are going to define a macro to do it, you may consider putting the whole thing in a \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!


I think that \savebox is better than a macro in this case, because a) what is in the box is self-contained (the typesetting of the content of the box does not depend on the location in the text) and b) it is relatively expensive to render and by using a \savebox you are telling the texengine to simply reuse the result of the rendering, while the macro would tell it to re-render everything from scratch.

-
Not a bad idea. – Matthew Leingang Oct 26 '10 at 20:13
Just to be sure, I checked it with a forloop, it is much much faster using savebox, than with a simple macro. ( I tried with a for loop that iterated 100 times). – Yossi Farjoun Oct 26 '10 at 21:51

With TiKZ 3.0 pics it's easy to reuse part of your image. You need to declare the reusable part inside a pic and place where you want, even inside a 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}


-
This example generates an empty page for me. I'm using Package: tikz 2013/12/13 v3.0.0 (rcs-revision 1.142). – Fernando César Oct 15 '15 at 22:42
@FernandoCésar I don't know which version I used in sep/2014 but worked and still works with more recent versions (I'm using a last week updated MikTeX system). With your information I can only suggest to update your TeX system or provide some more information. – Ignasi Oct 16 '15 at 6:27

The PGF manual speaks of the two following commands:

\pgfsys@defobject{⟨name⟩}{⟨lower left⟩}{⟨upper right⟩}{⟨code⟩}
Declares an object for later use. The idea is that the object can be precached in some way and then be rendered more quickly when used several times. For example, an arrow head might be defined and prerendered in this way. The parameter ⟨name⟩ is the name for later use. ⟨lower left⟩ and ⟨upper right⟩ are pgf points specifying a bounding box for the object. ⟨code⟩ is the code for the object. The code should not be too fancy. This command has a default implementation and need not be implemented by a driver file.

\pgfsys@useobject{⟨name⟩}{⟨extra code⟩}
Renders a previously declared object. The first parameter is the name of the the object. The second parameter is extra code that should be executed right before the object is rendered. Typically, this will be some transformation code. This command has a default implementation and need not be implemented by a driver file.

Unfortunately I never understood how those work, so consider this as an extended comment or a new question related to the original.

-