Assign a name to a TikZ picture for reusing it

If I want to reuse a TikZ picture I usually define a new command like

\newcommand{\mypic}{%
\begin{tikzpicture}
%...
\end{tikzpicture}%
}%

Then I reuse it later via \mypic.

However I think this is not very elegant. So my question is if it is possible to assign a name to the picture via a key, which can be called to reuse the picture at another place? For example:

\begin{tikzpicture}[rname=mypic]
%...
\end{tikzpicture}

And reuse it like \mypic or something like \rtikz{mypic}.

Would be even better if I could to things like this \rtikz[scale=0.5,every label/.style={red}]{mypic}.

-
I would consider storing the picture in a box instead. This is more efficient, but doesn't work if the picture should be context sensitive, e.g. certain parts should scale with the font size etc. –  Martin Scharrer May 20 '12 at 19:13
If you want to change the options then it really is going to need to be reprocessed in which case you have no other option than to save the commands as you would enter them, and that's what the definition is doing. If you don't want to make any changes then you could save the box that is created at the end and just reuse that. But then you couldn't make any changes. –  Loop Space May 20 '12 at 19:14
@PeterGrill I think the problem is the usage of \newcommand. It would be nice to have the ability to name the whole pictures, if you can name the nodes etc. anyways. –  yo' May 20 '12 at 19:14
I usually store TikZ pictures in separate files, one per file. This enables reusing them (with a simple \input), and also standalone compilation with, well, the standalone document class+package. –  krlmlr May 20 '12 at 19:45

(Must admit, this seems a little complicated when compared to just defining a new command ...)

Here's a method for doing what you ask: using a key on the main tikzpicture. It might very well break! It redefines the tikzpicture environment using Will Robertson's environ package. This package converts environments into macros making it easier to save their contents as written. So we do that to get the contents. Using it is a matter of restoring the original meaning of the tikzpicture environment and simply executing the saved macro.

\documentclass{article}
%\url{http://tex.stackexchange.com/q/56664/86}
\usepackage{tikz}
\usepackage{environ}

\makeatletter
\let\orig@tikzpicture=\tikzpicture
\let\orig@endtikzpicture=\endtikzpicture
\let\env@tikzpicture@save@env=\pgfutil@empty
\let\env@tikzpicture@process=\pgfutil@empty
\RenewEnviron{tikzpicture}[1][]{%
\begingroup
\let\tikzpicture=\orig@tikzpicture
\let\endtikzpicture=\orig@endtikzpicture
\let\tikz@picname=\pgfutil@empty
\begin{tikzpicture}[#1]
\BODY
\end{tikzpicture}
\ifx\tikz@picname\pgfutil@empty
\else
\expandafter\gdef\csname     tikz@savedpic@\tikz@picname\expandafter\endcsname\expandafter{\BODY}
\fi
\endgroup
}

\newcommand\usetikzpicture[2][]{%
\begingroup
\let\tikzpicture=\orig@tikzpicture
\let\endtikzpicture=\orig@endtikzpicture
\let\tikz@picname=\pgfutil@empty
\begin{tikzpicture}[#1]
\csname tikz@savedpic@#2\endcsname
\end{tikzpicture}
\endgroup}

\tikzset{
save picture as/.code={
\gdef\tikz@picname{#1}%
}
}
\makeatother
\begin{document}
\begin{tikzpicture}[save picture as=mypic]
\draw (0,0) -- (1,1);
\end{tikzpicture}
\usetikzpicture[every path/.style={red}]{mypic}
\end{document}

Result:

-

Use a box to save it, here an MWE:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes,arrows}
\begin{document}
\newsavebox{\mypicture}
\begin{lrbox}{\mypicture}
\begin{tikzpicture}[auto,>=latex']
\tikzstyle{block} = [draw, shape=rectangle, minimum height=3em, minimum width=3em, node distance=2cm, line width=1pt]
\tikzstyle{block1} = [draw,shape=rectangle, minimum height=3em, minimum width=3em, node distance=3cm, line width=1pt]
\tikzstyle{sum} = [draw, shape=circle, node distance=1.5cm, line width=1pt, minimum width=1.25em]
\tikzstyle{branch}=[fill,shape=circle,minimum size=4pt,inner sep=0pt]
\node at (-2.5,0) (input) {$x[n]$};
\node [block] (h1) {$h_1[n]$};
\node [block, right of=h1] (h2) {$h_2[n]$};
\node [sum, right of=h2] (sum) {};
\node at (sum) (plus) {{\footnotesize$+$}};
\node at (5,0) (output) {$y[n]$};
\path (h1) -- coordinate (med) (h2);
\path (input) -- coordinate(branch1) (h1);
\node [block, below of=med] (h3) {$h_3[n]$};
\begin{scope}[line width=1pt]
\draw[->] (input) -- (h1);
\draw[->] (h1) -- (h2);
\draw[->] (h2) -- (sum);
\draw[->] (sum) -- (output);
\draw[->] (branch1) node[branch] {} |- (h3);
\draw[->] (h3) -| (sum);
\end{scope}
\end{tikzpicture}
\end{lrbox}

\usebox{\mypicture}\par\vspace{10pt}
Lalalalalala\par\vspace{10pt}
\usebox{\mypicture}
\end{document}

It generates:

I guess you take in mind the hint of @Martin Scharrer about using boxes to solve this problem. I hope I helped you.

-
This should be the better method to repeat a figure inside a document, compared to the other ones. Thanks. –  Nicolás May 20 at 18:53

Create a set of appropriate PGF keys.

\pgfkeys{/pictures/.is family}
\def\cxset{\pgfqkeys{/pictures}}

\cxset{bar chart scale/.store in=\barchartscale@my,
bar chart/.store in=\barchartcolor@my,
bar chart font/.store in=\barchartfont@my,
bar chart draw/.code=\mypic}

You will not be able to avoid a new command to store the original,

\newcommand{\mypic}{%
\begin{tikzpicture}
%...
\end{tikzpicture}%
}%

However, this way you can define as many variables as you like, and save a lot of typing. Use your imagination for your application and have an easy to remember interface. For example, I am busy with an application that overlays the page parameters on a page as shown below:

Some of the parameters one can set are as follows:

\cxset{geometry lines color=orange,
geometry show grid,
geometry grid=10,
geometry units=cm}

Another advantage of this approach, is all the styling and the macros, go in a style file. You only draw with the cxset{}, which you can name with appropriate semantics.

This works well so far.

-
Is the second line intended to be bar chart/.store in=\barchartcolor@my. Also it would be useful to show an example of how you use those keys in the tikzpicture code. –  Peter Grill May 21 '12 at 6:00
@PeterGrill Sorry should be bar chart color/.store\barchartcolor@my thanks for spotting it. Will post a minimal tonight as well, good idea. –  Yiannis Lazarides May 21 '12 at 7:27