[Tex/LaTex] TiKZ node name prefixes in scopes

nodestikz-pgf

I am using TiKZ to draw two copies of the same graph above each other, and now I want to add edges between a vertex in one copy and a vertex in the other copy. It suddenly occurred to me that it would be nice if I could put each copy in a separate scope, give each scope a name, and refer to nodes inside the scope in an "object oriented" way by referring to the node as <scope name>.<node name>. To illustrate, it would be cool if I could do something like this:

\documentclass{article}

\usepackage{tikz}

\begin{document}

\tikzstyle{vertex}=[circle,draw,fill=black!20]

\begin{tikzpicture}

% ---- Copy 1
\begin{scope}[yshift=-32pt,name=G1]
  \node[vertex] (u) at (0, 0) {u};
  \node[vertex] (v) at (0, 0) {v};
\end{scope}

% ---- Copy 2
\begin{scope}[yshift=32pt,name=G2]
  \node[vertex] (u) at (0, 0) {u};
  \node[vertex] (v) at (0, 0) {v};
\end{scope}

\draw (G1.u) -- (G2.v);

\end{tikzpicture}

\end{document}

Here, I refer to node u of scope G1 as G1.u, and to node v of scope G2 as G2.v.

Is something like this possible in TiKZ?

Best Answer

Here's a simple hack that redefines the naming code inside the scope to append a prefix. You can't use a . as a separator though as that would confuse the parser. I've used a space, but you could use something else (some punctuation, such as . is special, there's a list somewhere here).

\documentclass{article}
%\url{http://tex.stackexchange.com/q/128049/86}

\usepackage{tikz}

\begin{document}

\tikzstyle{vertex}=[circle,draw,fill=black!20]

\makeatletter
\tikzset{%
  prefix node name/.code={%
    \tikzset{%
      name/.code={\edef\tikz@fig@name{#1 ##1}}
    }%
  }%
}
\makeatother

\begin{tikzpicture}

% ---- Copy 1
\begin{scope}[yshift=-32pt,prefix node name=G1]
  \node[vertex] (u) at (0, 0) {u};
  \node[vertex] (v) at (0, 0) {v};
\end{scope}

% ---- Copy 2
\begin{scope}[yshift=32pt,prefix node name=G2]
  \node[vertex] (u) at (0, 0) {u};
  \node[vertex] (v) at (0, 0) {v};
\end{scope}

\draw (G1 u) -- (G2 v);

\end{tikzpicture}

\end{document}

Note that this works both with implicit and explicit naming of nodes (ie via name=<name> and \node (name) ...).