# pic versus macro in TikZ

Consider this code in the TikZ - PGF manual, which uses a macro

% Main code from
% The TikZ - PGF manual
%   Author: Till Tantau et al
%   Version 3.1.3, released May 9, 2019
%   Page 40
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\def\rectanglepath{-- ++(1cm,0cm) -- ++(0cm,1cm) -- ++(-1cm,0cm) -- cycle}
\draw (0,0) \rectanglepath;
\draw (1.5,0) \rectanglepath;
\end{tikzpicture}
\end{document}


and this one written by me, which uses pic

\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
[rectanglepath/.pic={\draw (0,0)--++(1cm,0cm)--++(0cm,1cm)--++(-1cm,0cm)--cycle;}]
\pic at (0,0) {rectanglepath};
\pic at (1.5,0) {rectanglepath};
\end{tikzpicture}
\end{document}


Both give us the same output

### Observation

Both give the same output. I prefer the latter one, as it is more "TikZ-ish". However, we can always change a code from pic to macro and vice versa, as above (am I wrong – is there a case in which we can't convert?), or draw the same figure using two different codes (this and this for example).

Also, I can't see any aspects in which macros are better than pic. Even arguments: we can also have pic with up to nine arguments with any pattern using /.style args.

In the PGF manual, sometimes I see pic is used, but sometimes a macro is used (it is even used in the title page!). From those examples, I can't figure out in what case I should use a macro and in what case I should use a pic.

### Question

It may be quite clear by now.

If I have to draw the same "sub-"picture many times in a TikZ picture, should I use a pic or a macro? And why? Is there any cases in which I must use this one and not the other?

### Edit

As for @marmot's nice codes, I have written myself some code (against it) which uses macros

\documentclass{article}
\usepackage{tikz}
\begin{document}
\subsection*{Macros can have more complicated constructions}

\begin{tikzpicture}%[rectanglepath/.pic={\draw (-0.5,-0.5) rectangle ++(1,1);
%\draw[red] (-0.5,0.5) -- (0.5,-0.5);}]
\newcommand\rectanglepath[2][]{\scope[shift={(#2)},#1]\draw (-0.5,-0.5) rectangle ++(1,1);
\draw[red] (-0.5,0.5) -- (0.5,-0.5);\endscope}
%\path (0,0) pic{rectanglepath} (2,0) pic[dashed]{rectanglepath};
\rectanglepath{0,0}
\rectanglepath[dashed]{2,0}
\end{tikzpicture}

\subsection*{Macros can have names}

\begin{tikzpicture}%[rectanglepath/.pic={\draw (-0.5,-0.5) rectangle ++(1,1);
%\draw[red] (-0.5,0.5) coordinate(-tl)  -- (0.5,-0.5) coordinate(-br) ;}]
\newcommand\rectanglepath[3][]{\scope[shift={(#2)},#1]\draw (-0.5,-0.5) rectangle ++(1,1);
\draw[red] (-0.5,0.5) coordinate (#3-tl)
-- (0.5,-0.5) coordinate (#3-br);\endscope}
%\path (0,0) pic (A) {rectanglepath} (2,0) pic[dashed] (B) {rectanglepath};
\rectanglepath{0,0}{A}
\rectanglepath[dashed]{2,0}{B}
\draw (A-tl) to[out=30,in=150] (B-tl) (A-br) to[out=-30,in=-150] (B-br);
\end{tikzpicture}

\subsection*{Transformations are much more intuitive on macros}

\begin{tikzpicture}[rectanglepath/.pic={\draw (-0.5,-0.5) rectangle ++(1,1);}]
\newcommand\rectanglepath[2][]
{\scope[shift={(#2)},#1]\draw (-0.5,-0.5) rectangle ++(1,1);\endscope}
%\path (0,0) pic[rotate=45]{rectanglepath} (2,0) pic[dashed,rotate=-30]{rectanglepath}
%(4,0) pic[thick,xscale=0.5]{rectanglepath};
\rectanglepath[rotate=45]{0,0}
\rectanglepath[rotate=-30,dashed]{2,0}
\rectanglepath[thick,xscale=0.5]{4,0}
\end{tikzpicture}
\end{document}


• My experience is that pics are faster. For example, the threads on a screw. May 25 '19 at 13:45
• @JohnKormylo If yes, probably it is faster on very long documents. On reports I usually write, they are equal in time taken
– user156344
May 25 '19 at 15:16

Here are threefour examples of things that are much harder to achieve in the macro approach. The first three examples have been translated to macros in the revised question.

\documentclass{article}
\usepackage{tikz}
\begin{document}
\subsection*{Pics can have more complicated constructions}
\tikzset{rectanglepath/.pic={\draw (-0.5,-0.5) rectangle ++(1,1);
\draw[red] (-0.5,0.5) coordinate(-tl)  -- (0.5,-0.5) coordinate(-br) ;}}

\begin{tikzpicture}
\path (0,0) pic{rectanglepath} (2,0) pic[dashed]{rectanglepath};
\end{tikzpicture}

\subsection*{Pics can have names}

\begin{tikzpicture}
\path (0,0) pic (A) {rectanglepath} (2,0) pic[dashed] (B) {rectanglepath};
\draw (A-tl) to[out=30,in=150] (B-tl) (A-br) to[out=-30,in=-150] (B-br);
\end{tikzpicture}

\subsection*{Transformations are much more intuitive on pics}

\begin{tikzpicture}
\path (0,0) pic[rotate=45]{rectanglepath} (2,0) pic[dashed,rotate=-30]{rectanglepath}
(4,0) pic[thick,xscale=0.5]{rectanglepath};
\end{tikzpicture}

\subsection*{You can insert pics in paths}

\begin{tikzpicture}[xboard/.style={insert path={
(0,0) grid (#1,#1)
foreach \X in {1,...,#1}
{(\X-0.5,\X-0.5) pic{rectanglepath} (\X-0.5,#1-\X+0.5) pic[rotate=90]{rectanglepath}}}}]
\draw[xboard=1,xshift=2cm,xboard=3,xshift=4cm,xboard=5];
\end{tikzpicture}

\end{document}


My personal take: pics win, at least in the above-described scenarios. IMHO the translated macros in the revised question substantiate this.

Notice that "behind the scenes" pics are macros at some level. So you will always be able to reproduce the outcome of a pic with a macro. However, the effort will be more substantial. And yes, if you are in the mood to do some unnecessary extra work, you can use macros instead of pics. So, yes, the choice can depend on the mood of the day.

Let me also stress that there are scenarios in which pics perform worse. An example of this type may be a life wheel.

BTW, there is also the insert path option that is sometimes preferable over pics IMO.

• +1: Perfect answer! May 25 '19 at 13:42
• @JouleV Well, at some level a pic is a macro. My point is simply that things are harder to achieve with macros, and your macros substantiate this. I never claimed that you cannot achieve things done with a pic also with a macro, it is just harder and also less elegant IMHO.
– user121799
May 25 '19 at 15:42
– user121799
May 25 '19 at 15:55
• but \foreach \X in {1,2,3} {\begin{tikzpicture} \newcommand\rectanglepath[2][]{\scope[shift={(#2)},#1]\draw (-0.5,-0.5) rectangle ++(1,1); \draw[red] (-0.5,0.5) -- (0.5,-0.5);\endscope} \rectanglepath{0,0} \rectanglepath[dashed]{2,0} \end{tikzpicture}} doesn't. (Yes, I know how to fix it but it is, again, more complicated.)
– user121799
May 25 '19 at 15:55
• @JouleV I tried to answer the question If I have to draw the same "sub-"picture many times in a TikZ picture, should I use a pic or a macro? And why?. My answer is that in most situations pics are less complicated, which is why they are arguably preferable.
– user121799
May 25 '19 at 16:48