25

If I have two tikzpictures drawn:

\documentclass{article}
\usepackage[margin = 1in]{geometry}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing,calc,shapes,shapes.geometric,patterns}
\begin{document}

\tikzset{treetop/.style = {decoration={random steps, segment length=0.4mm},decorate},trunk/.style = {decoration={random steps, segment length=2mm, amplitude=0.2mm},decorate}}

\begin{tikzpicture}
\foreach \w/\f in {0.3/30,0.2/50,0.1/70} {
\fill [brown!\f!black, trunk] (0,0) ++(-\w/2,0) rectangle +(\w,-3);
}
\foreach \n/\f in {1.4/40,1.2/50,1/60,0.8/70,0.6/80,0.4/90} {
   \fill [green!\f!black, treetop] ellipse (\n/1.5 and \n);
}
\end{tikzpicture}

\begin{tikzpicture}
\shade[bottom color=cyan!60!black, top color=blue!20!white] (0,0) rectangle (10,10);
\end{tikzpicture}

\end{document}

enter image description here

How could I use the first tikz picture within the second? Can I define the first picture as some variable and then place this variable within the second picture and have the option of defining its exact location (x,y) and its size? For example, if I wanted to place the tree in the middle of the rectangle (5,5) but make the size of the tree half its current size. How would I do this

  • Can it be a duplicate of tex.stackexchange.com/questions/37823/… – percusse Jul 31 '13 at 8:01
  • How about using the background canvas via ´\begin{scope}[background] ... \end{scope}´ for the second image? (I am still a beginner.) – Jan Apr 3 '18 at 9:53
18

I would define a specific key for the tree and one for the position:

% to get the positions of last x,y
\newdimen\xval
\newdimen\yval

\pgfkeys{/tikz/.cd,
   at/.initial={(0,0)},
   at/.get=\coordpos,
   at/.store in=\coordpos,   
   my tree/.code={
     \foreach \w/\f in {0.3/30,0.2/50,0.1/70} {
       \fill [brown!\f!black, trunk] \coordpos ++(-\w/2,0) rectangle +(\w,-3);
     }
     \pgfgetlastxy{\xval}{\yval};
     \foreach \n/\f in {1.4/40,1.2/50,1/60,0.8/70,0.6/80,0.4/90} {
       \fill [green!\f!black, treetop](\xval,\yval) ellipse (\n/1.5 and \n);
     }
   }
}

so that in the final picture you can use:

\begin{tikzpicture}
\shade[bottom color=cyan!60!black, top color=blue!20!white] (0,0) rectangle (10,10);
\node[at={(2.5,5)},my tree]{};
\node[at={(5,5)},my tree]{};
\node[at={(7.5,5)},my tree]{};
\end{tikzpicture}

The complete code:

\documentclass{article}
\usepackage[margin = 1in]{geometry}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing,calc,shapes,shapes.geometric,patterns}
\begin{document}

\tikzset{treetop/.style = {decoration={random steps, segment length=0.4mm},decorate},trunk/.style = {decoration={random steps, segment length=2mm, amplitude=0.2mm},decorate}}

% to get the positions of last x,y
\newdimen\xval
\newdimen\yval

\pgfkeys{/tikz/.cd,
   at/.initial={(0,0)},
   at/.get=\coordpos,
   at/.store in=\coordpos,   
   my tree/.code={
     \foreach \w/\f in {0.3/30,0.2/50,0.1/70} {
       \fill [brown!\f!black, trunk] \coordpos ++(-\w/2,0) rectangle +(\w,-3);
     }
     \pgfgetlastxy{\xval}{\yval};
     \foreach \n/\f in {1.4/40,1.2/50,1/60,0.8/70,0.6/80,0.4/90} {
       \fill [green!\f!black, treetop](\xval,\yval) ellipse (\n/1.5 and \n);
     }
   }
}

\begin{tikzpicture}
\shade[bottom color=cyan!60!black, top color=blue!20!white] (0,0) rectangle (10,10);
\node[at={(2.5,5)},my tree]{};
\node[at={(5,5)},my tree]{};
\node[at={(7.5,5)},my tree]{};
\end{tikzpicture}

\end{document}

The result:

enter image description here

  • 1
    +1 Much more elegant solution than mine. I need to get up to speed on pgfkeys! – jub0bs Jul 31 '13 at 8:17
  • @Jubobs: definitely ;) – Claudio Fiandrino Jul 31 '13 at 8:37
  • +100 This is brilliant. You just helped me save hundreds of lines of code as I had lots of variations on the same image throughout a document. I don't know if it's correct or not, but specifying coordinates within a node works as well. – Robbie Oct 31 '16 at 5:13
36

TiKZ 3.0.0 introduces pic a "short picture" which can be inserted in any place of a tikzpicture. A possible solution with 'pic' would be:

\documentclass{standalone}
\usepackage[margin = 1in]{geometry}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing,calc,shapes,shapes.geometric,patterns}
\begin{document}

\tikzset{treetop/.style = {decoration={random steps, segment length=0.4mm},decorate},trunk/.style = {decoration={random steps, segment length=2mm, amplitude=0.2mm},decorate}}

\tikzset{
   my tree/.pic={
     \foreach \w/\f in {0.3/30,0.2/50,0.1/70} {
       \fill [brown!\f!black, trunk] (-\w/2,0) rectangle +(\w,3);
     }
     \foreach \n/\f in {1.4/40,1.2/50,1/60,0.8/70,0.6/80,0.4/90} {
       \fill [green!\f!black, treetop](0,3) ellipse (\n/1.5 and \n);
     }
   }
}

\begin{tikzpicture}
\shade[bottom color=cyan!60!black, top color=blue!20!white] (0,0) rectangle (10,10);
\pic at (2,2) {my tree};
\pic at (4,2.5) {my tree};
\pic at (6,1.75) {my tree};
\end{tikzpicture}

\end{document}

enter image description here

  • You deserve more upvotes. This is the most elegant variant. – Ingo Jan 11 '14 at 12:06
  • Is there anyway of adding a parameter to control features, such as the size? – mattdns May 2 '16 at 17:43
  • @mattdns you can try with \pic[scale=0.8] at (...) {my tree}; – Ignasi May 2 '16 at 18:32
6

Let us define a newcommand:

\newcommand\myfig[2]{%
    \begin{scope}[xshift=#1cm,yshift=#2cm]
        \foreach \w/\f in {0.3/30,0.2/50,0.1/70} {%
            \fill [brown!\f!black, trunk] (0,0) ++(-\w/2,0) rectangle +(\w,-3);
            }
        \foreach \n/\f in {1.4/40,1.2/50,1/60,0.8/70,0.6/80,0.4/90} {%
            \fill [green!\f!black, treetop] ellipse (\n/1.5 and \n);
            }
    \end{scope}
}

And use it like this:

\documentclass{article}
\usepackage[margin = 1in]{geometry}
\usepackage{tikz}
\usetikzlibrary{decorations.pathmorphing,calc,shapes,shapes.geometric,patterns}

\newcommand\myfig[2]{%
    \begin{scope}[xshift=#1cm,yshift=#2cm]
        \foreach \w/\f in {0.3/30,0.2/50,0.1/70} {%
            \fill [brown!\f!black, trunk] (0,0) ++(-\w/2,0) rectangle +(\w,-3);
            }
        \foreach \n/\f in {1.4/40,1.2/50,1/60,0.8/70,0.6/80,0.4/90} {%
            \fill [green!\f!black, treetop] ellipse (\n/1.5 and \n);
            }
    \end{scope}
}
\begin{document}
\tikzset{treetop/.style = {decoration={random steps, segment length=0.4mm},decorate},trunk/.style = {decoration={random steps, segment length=2mm, amplitude=0.2mm},decorate}}

\begin{tikzpicture}
    \myfig{0}{0}
\end{tikzpicture}

\begin{tikzpicture}
    \shade[bottom color=cyan!60!black, top color=blue!20!white] (0,0) rectangle (10,10);
    \myfig{2.5}{5}
    \myfig{5}{5}
    \myfig{7.5}{5}    
\end{tikzpicture}

\end{document}

enter image description here

  • I think, this is very elegant, too. And---just in case---it solved my actual problem very well! Thank you! – Jan Apr 3 '18 at 9:56
5

Yes, it can be done with a pgfonlayer environment within the tikzpicture and a new command (called \treedrawing below) that takes as argument the coordinates (of the form x,y) of the tree and draws it there. Just make sure to call \treedrawing after the pgfonlayer environment, or your trees will be behind the background.

enter image description here

\documentclass{article}
\usepackage[margin = 1in]{geometry}
\usepackage{tikz}
\usetikzlibrary{%
    backgrounds,%
    decorations.pathmorphing,%
    calc,%
    shapes,%
    shapes.geometric,%
    patterns,%
}

\begin{document}

\newcommand\treedrawing[1]{%
    \tikzset{%
        treetop/.style = {decoration    = {random steps, segment length=0.4mm},decorate},%
        trunk/.style = {decoration={random steps, segment length=2mm, amplitude=0.2mm},decorate}%
    }
\begin{scope}[shift={(#1)}]
    \foreach \w/\f in {0.3/30,0.2/50,0.1/70}{%
        \fill [brown!\f!black, trunk] (0,0) ++(-\w/2,0) rectangle +(\w,-3);
    }
    \foreach \n/\f in {1.4/40,1.2/50,1/60,0.8/70,0.6/80,0.4/90}{%
        \fill [green!\f!black, treetop] ellipse (\n/1.5 and \n);
    }
\end{scope}
}

\begin{tikzpicture}
    \begin{pgfonlayer}{background}
        \shade[bottom color=cyan!60!black, top color=blue!20!white] (0,0) rectangle (10,10);
    \end{pgfonlayer}
    \treedrawing{2,5}
    \treedrawing{5,5}
    \treedrawing{8,5}
\end{tikzpicture}
\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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