6

In previous versions of tikz the solution of naming pics using a local bounding box used to work.

However, in the version 3.1.10, the previous code produces the error:

! Package pgf Error: No shape named `A1' is known.
! Package pgf Error: No shape named `A2' is known.

What changed? How can I make the previous solution work with the new version?

Code

The previous solution is here for completeness:

\documentclass[tikz,border=5]{standalone}
\usetikzlibrary{fit}%
\makeatletter
\tikzset{pics/named scope code/.style={code={\tikz@fig@mustbenamed%
  \begin{scope}[local bounding box/.expanded=\tikz@fig@name]#1\end{scope}%
}}}
\makeatother

\tikzset{pics/.cd,
  pic a/.style={named scope code={
      \node [fill=red!20, shape=circle] {A};
  }}
}

\begin{document}
\begin{tikzpicture}
\pic (A1) at (0,0) {pic a};
\pic (A2) at (3,0) {pic a};
\foreach \i in {0,15,...,345}{
  \draw [red, ->] (\i:1) -- (A1);
  \draw [blue, ->] (3,0)++(\i:1) -- (A2);
}
\end{tikzpicture}
\end{document}

Setup

Compiling with pdflatex: pdfTeX, Version 3.141592653-2.6-1.40.26 (TeX Live 2024)

Packages:

  • Document Class: standalone 2022/10/10 v1.3b Class to compile TeX sub-files standalone
  • Package: pgfrcs 2023-01-15 v3.1.10 (3.1.10)
  • Package: pgfcore 2023-01-15 v3.1.10 (3.1.10)
  • Package: tikz 2023-01-15 v3.1.10 (3.1.10)
  • File: tikzlibraryfit.code.tex 2023-01-15 v3.1.10 (3.1.10)
3
  • 1
    Do [local bounding box=]. The key prefixes the pic's name internally. (Just like a node would.) Commented Jul 11 at 9:29
  • That solved the errors. Why it used to work and now it doesn't?
    – adn
    Commented Jul 11 at 9:41
  • 3
    They made the key aware of the name prefix for v3.1.10. (The pic's name is setup as a name prefix internally.) Commented Jul 11 at 9:48

1 Answer 1

5

Since version v3.1.10 TikZ includes both name prefix and name suffix for the local bounding box. Since the pic's name is appended to the name prefix this would be applied twice, meaning that the bounding boxes are actually named A1A1 and A2A2:

\draw [red, ->] (\i:1) -- (A1A1);
\draw [blue, ->] (3,0)++(\i:1) -- (A2A2);

The fix is simple.

We give the local bounding box an empty name as we would give it to a node that should take the name of the pic:

\tikzset{% /tikz/local bounding box
  pics/named scope code/.style={code={\tikz@fig@mustbenamed
    \begin{scope}[local bounding box=]#1\end{scope}}}}

Alternatively, we use the previous implementation by using the PGF version of the key with \tikz@fig@name again:

\tikzset{% /pgf/local bounding box
  pics/named scope code/.style={code={\tikz@fig@mustbenamed
    \begin{scope}[/pgf/local bounding box/.expanded=\tikz@fig@name]#1\end{scope}}}}

Code

\documentclass[tikz, border=5pt]{standalone}
\makeatletter
\tikzset{% /tikz/local bounding box
  pics/named scope code/.style={code={\tikz@fig@mustbenamed
    \begin{scope}[local bounding box=]#1\end{scope}}}}
%\tikzset{% /pgf/local bounding box
%  pics/named scope code/.style={code={\tikz@fig@mustbenamed
%    \begin{scope}[/pgf/local bounding box/.expanded=\tikz@fig@name]#1\end{scope}}}}
\makeatother
\tikzset{pics/.cd,
  pic a/.style={named scope code={
      \node [fill=red!20, shape=circle] {A};}}}
\begin{document}
\begin{tikzpicture}
\pic (A1) at (0,0) {pic a};
\pic (A2) at (3,0) {pic a};
\foreach \i in {0,15,...,345}{
  \draw [red, ->] (\i:1) -- (A1);
  \draw [blue, ->] (3,0)++(\i:1) -- (A2);
}
\end{tikzpicture}
\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .