TikZ: position a pic with its inner coordinate

alignmenttikz-nodetikz-pgftikz-pic

In the MWE below, I made a TikZ pic called bus with one argument. The argument creates nodes within the pic that will be used as connection points to other buses. I would like to align these pics by their connection points, i.e., the nodes within them. So in the picture below, the 1 on the right should be in-line with the 2 on the left (vertically centered). But I would love the flexibility of aligning that 1 on the right bus with 1, 2, or 3 on the left bus.

Is this possible? The code I tried failed I think, because the position command to pic defines the origin that the pic is made from, so there isn't any coordinate b-1 in the pic at that time. This is a very simple example, and while I'm not married to using pics, the prospect of using them for this sort of thing is enticing to make building blocks for complex diagrams.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usetikzlibrary{calc}

\begin{document}

\def\busnodespace{3mm}
\tikzset{
pics/bus/.style n args={1}{
        code = { %
            \draw[ultra thick] (0, {-0.75*\busnodespace}) -- (0, {(#1-1+0.75)*\busnodespace});
            \foreach \y in {1,...,#1} {\node[inner sep=0pt] (-\y) at (0.0,{(\y-1)*\busnodespace}) {\color{red}{\scriptsize\y}};}
        }}}

\begin{tikzpicture}
    \pic (a) at (0,0) {bus=3}; % bus of size 3
%    \pic (b) at (2,0) {bus=1}; % bus of size 1 -- is it possible to position this (elegantly, hopefully with no math)
                                % so coordinate b1 is in line with a2?
                               % ie I would like a flat line
%    \pic[right=of a-2] (b) {bus=1};  % obv this wont cut
    \pic[right=of a-2,anchor=b-1] (b) {bus=1}; ; this doesn't work because b isn't made in time for the position to be applied
    \draw (a-2) -- (b-1);

\end{tikzpicture}

\end{document}

Enter image description here

Best Answer

Like this?

enter image description here

Positioning of pic can be tricky, however in your case relative positioning to nodes in pic works fine. In MWE below the code for pic is simplified and a bit reorganized:

\documentclass[border=3.141592, varwidth]{standalone}
\usepackage{tikz}
\usetikzlibrary{backgrounds, % new
                positioning}

\begin{document}

\def\busnodespace{3mm}
\tikzset{
pics/bus/.style ={
        code = { % 
            \foreach \i [count=\y from 0] in {1,...,#1} 
                {
                \node[inner xsep=0pt, inner ysep=\busnodespace/2,
                      font=\scriptsize, text=red] (-n\i) at (0,\y*\busnodespace) {\i};
                }
            \scoped[on background layer] 
            \draw[ultra thick] (-n1.south) -- (-n#1.north);
}
        }}

\begin{tikzpicture}
    \pic (a)                    {bus=3};  % bus of size 3
    \pic (b) [right=of a-n2]    {bus=1};  % bus of size 1 
    \draw[gray] (a-n2) -- (b-n1);
\end{tikzpicture}

\medskip
\begin{tikzpicture}
    \pic (a)                    {bus=3};  % bus of size 3
    \pic (b) [right=of a-n1]    {bus=2};  % bus of size 1
    \draw[gray] (a-n1) -- (b-n1);
\end{tikzpicture}

\medskip
\begin{tikzpicture}
    \pic (a)                    {bus=3};  % bus of size 3
    \pic (b) [right=of a-n3]    {bus=1};  % bus of size 1
    \draw[gray] (a-n3) -- (b-n1);
\end{tikzpicture}

\end{document}

Addendum: One more option. If you define anchor of ˙pic` with coordinate on the middle of it, than you can positioned second pic for example as:

\documentclass[border=3.141592]{standalone}
\usepackage{tikz}
\usetikzlibrary{backgrounds,
                positioning}

\begin{document}
    \begin{tikzpicture}[
  node distance = 0mm and 15mm,
pics/bus/.style = {code = {\foreach \i [count=\y from 0] in {1,...,#1}
                           \node[inner xsep=0pt, inner ysep=\busnodespace/2,
                                 font=\scriptsize, text=red] (-n\i) at (0,\y*\busnodespace) {\i};
                           \scoped[on background layer]
                           \draw[ultra thick] (-n1.south) -- coordinate (-@c) (-n#1.north);}}  % <---
                    ]
\def\busnodespace{3mm}
\pic (a)                    {bus=2}; 
\pic (b) [below right=3*\busnodespace and 15mm of a-@c]    {bus=3};  
\draw[gray] (a-n1) -- (b-n3);
    \end{tikzpicture}
\end{document}

enter image description here

The same result you will get with the following image body:

\pic (a)                    {bus=2};  
\pic (b) [right= of a-n1, yshift=-2*\busnodespace]    {bus=3}; 
\draw[gray] (a-n1) -- (b-n3);
Related Question