16

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

enter image description here

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?

Thanks in advance.


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}

enter image description here

  • My experience is that pics are faster. For example, the threads on a screw. – John Kormylo 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 –  May 25 '19 at 15:16

1 Answers1

12

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}

enter image description here

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
    +1: Perfect answer! – Dr. Manuel Kuehner May 25 '19 at 13:42
  • I just successfully made a code for the same thing which uses a macro. See my edit above –  May 25 '19 at 15:09
  • @JouleV Yes, this illustrates my point "much harder to achieve" very well. You have to rewrite the macro for each scenario in a different way whereas I can use the same pic everywhere. –  May 25 '19 at 15:13
  • @marmot I don't think I wrote them in different ways. I only put the code inside a \scope[shift={(#2)},#1]...\endscope, and... well, that's all –  May 25 '19 at 15:14
  • @JouleV These are different macros. –  May 25 '19 at 15:15
  • @marmot What do you mean by different? I basically copy and paste the main code and do some little adjustments for each pic, as your pics are different. In other words: your pics are similar (not the same) and so are my macros –  May 25 '19 at 15:17
  • The first thingy has \newcommand\rectanglepath[2][]{...}, the next \newcommand\rectanglepath[3][]{...}, they are not the same. –  May 25 '19 at 15:19
  • @marmot Well, it is like you have a pic with one argument, you can use /.pic or /.style, but if your pic has more than one, you need /.style args or /.style n args etc. –  May 25 '19 at 15:22
  • @JouleV This is precisely the point: I did not need to use any of these arguments here. I have spared them for things that may really need them. –  May 25 '19 at 15:23
  • @marmot I'm afraid my question is about pic vs macros with any number of arguments. It is very true that pic is much better than macros if there is only 1 or 0 arg, but that is not the general case. pic can have 9 args, macros can only have 7 args, but I don't think that really makes sense - we rarely use more than five but we may use more than one –  May 25 '19 at 15:25
  • 2
    @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. –  May 25 '19 at 15:42
  • 2
    @JouleV You also misinterpreted "The first thingy has \newcommand\rectanglepath[2][]{...}, the next \newcommand\rectanglepath[3][]{...}, they are not the same. ". The point is that you have to write different macros for different situations, and if you want to have the combined functionality, things become even more complicated. BTW, \foreach \X in {1,2,3} {\begin{tikzpicture}[rectanglepath/.pic={\draw (-0.5,-0.5) rectangle ++(1,1); \draw[red] (-0.5,0.5) -- (0.5,-0.5);}] \path (0,0) pic{rectanglepath} (2,0) pic[dashed]{rectanglepath}; \end{tikzpicture}} works ... –  May 25 '19 at 15:55
  • 1
    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.) –  May 25 '19 at 15:55
  • I'm afraid you misinterpreted my question. What I mean is that, is there a case in which we must use one of the two. I am not afraid of complications. If it can be drawn using both ways, I can choose and it depends on my mood on that day. This question does not focus on that. –  May 25 '19 at 16:00
  • 1
    @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. –  May 25 '19 at 16:48
  • nice answer for nice question! I want to add a remark: "node" is a special feature of TikZ, and "pic" is an advanced version of "node". Roughly speaking, along a path, we can add text using "node", and we can add small picture using "pic" . Meanwhile the command \def only replacing text/command, we can do more with node and pic, such as applying coordinate transformations – Black Mild May 26 '19 at 17:13
  • 1
    @BlackMild Thanks! I am not 100% sure I agree. A node has all sorts of anchors, which a pic does not have by default. Also a pic can contain nodes but if you embed pics in a node (using path picture, say) things are not very stable according to my experience. But I agree that they share many things. Something that is not appreciated very often is that you use pics in a matrix in pretty much the same way you can use nodes. –  May 26 '19 at 17:30
  • @TheoldJouleV macros can have 9 arguments as well. And I think it boils down to mood dependent. There might be things that are easier to do with pic, but you can do anything using the macro approach. And while I'm not sure how to put conditionals in a pic I know how to put those in macros, but that might be because of my limited knowledge in TikZ. – Skillmon May 27 '19 at 07:32
  • @Skillmon However, the examples above show that, in order to reproduce the things I did with pics with macros, these macros need to come with arguments. That is, the macro based approach uses up arguments while the pics don't. So in cases where you need many arguments, you may be fine with pics but not with macros. Of course, you can always get rid of the number of argument restriction by using pgf keys, but this is what pics do anyway, which is IMHO another point in favor of them. In fact, so far there was not a single example mentioned in which pics have drawbacks (but there are). –  May 27 '19 at 11:56
  • @marmot the arguments are a design choice, the pics use pgfkeys as well as a macro could. There is no real difference here. One could as well argue that you always have to use pic{<name-of-pic} while a macro would just be \name-of-macro, so a macro has fewer keystrokes. – Skillmon May 27 '19 at 12:12
  • @Skillmon As I said above, at some level a pic is a macro, so, yes, you will always be able to reproduce the features obtained with a pic with a macro. However, I do not buy your last point, simply because the above examples show that macros (tend to) require more key strokes. This is because pics have several features built in which you need to redo by hand if you use macros. Also you can use names for pics which you cannot use for macros because they already are used. –  May 27 '19 at 12:22
  • @marmot same is true for pics, they are just something like \pgf@tikz@pic@<name of pic> (didn't look into the sources, the actual name might differ), so a name clash might be more unlikely. This whole discussion doesn't make much sense to me, there is no real difference except in a design choice which is mood/user dependent. – Skillmon May 27 '19 at 13:01
  • @Skillmon Well, if you say that the discussion/question does not make sense, you should tell this the OP. I maintain my opinion that in most cases I know of pics are more elegant and should thus be preferred. –  May 27 '19 at 13:04