Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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

share|improve this question
    
I would think the best way to do this would be to simply extend the \newcommand to accept an optional parameter: \newcommand{\mypic}[1][]{\begin{tikzpicture}[#1]...\end{tikzpicture}}. Not sure why you think the other syntax would be any easier to use. –  Peter Grill May 20 '12 at 19:10
4  
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
2  
@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
5  
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

3 Answers 3

(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:

reusing tikzpictures

share|improve this answer

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:

Reusing a figure

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

share|improve this answer
1  
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:

enter image description here

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.

share|improve this answer
    
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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.