Tikz: ¿Cómo anidar nodos en una matriz para que puedan conectarse?

Tikz: ¿Cómo anidar nodos en una matriz para que puedan conectarse?

Quiero hacer una matriz que tenga múltiples nodos en una sola celda de la matriz. Estos nodos deben estar centrados entre sí. Logré que esto funcionara usando un entorno tikz anidado como este:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}
\usetikzlibrary{positioning}
\begin{document}

\begin{tikzpicture}[auto, semithick]
    \tikzstyle{block} = [rectangle, draw, 
        minimum width=5em, text centered, rounded corners, minimum
        height=4em] 

    \matrix[matrix of nodes, row sep = 2em,
    nodes={anchor=center}
    ] (mx2){
        % First row:
        label1
        & 
        \node{\tikz{
            \node[block](n1){node1}; 
            \node[block, right=of n1](n2){node2}; 
        }};
        \\
        % Second row:
        label2
        &
        \node{\tikz{
            \node[block] (n3) 
            {node 3};
            \node[block] (n4) [right=of n3] 
            {node 4};
            \node[block] (n5) [right=of n4] 
            {node 5};
        }};
        \\
        };
    \draw (n1) -- (n4); % this fails
\end{tikzpicture}

\end{document}  

ingrese la descripción de la imagen aquí

Ahora conectar estos nodos es imposible debido a los entornos tikz anidados. Intenté obtener una imagen similar usando la fitbiblioteca, pero no logré que funcionara. ¿Alguno de ustedes puede ayudarme?

Gracias de antemano.

Respuesta1

En general se puede utilizar la remember pictureopción y aplicarla.todoimágenes, que deberían ser accesibles más tarde. Dado que sus imágenes están anidadas y las opciones son heredables, es suficiente aplicarlas remember picturesolo al nivel superior {tikzpicture}.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}
\usetikzlibrary{positioning}
\begin{document}

\begin{tikzpicture}[auto, semithick, remember picture,
    block/.style={rectangle, draw, 
        minimum width=5em, text centered, rounded corners,
        minimum height=4em, text width=5em}
    ]
    \matrix[matrix of nodes, row sep = 2em,
    nodes={anchor=center}
    ] (mx2){
        % First row:
        label1
        & 
        \node{\tikz{
            \node[block] (n1) {node1}; 
            \node[block, right=of n1] (n2) {node2}; 
        }};
        \\
        % Second row:
        label2
        &
        \node{\tikz{
            \node[block] (n3) {node 3};
            \node[block] (n4) [right=of n3] {node 4};
            \node[block] (n5) [right=of n4] {node 5};
        }};
        \\
    };
    \draw (n1) -- (n4); % this works
\end{tikzpicture}

\end{document} 

resultado

Compile dos veces para obtener el resultado correcto.

Tenga en cuenta que lo reemplacé \tikzstyle{block}por block/.stylecuál es la forma preferida. Ver¿Debería usarse \tikzset o \tikzstyle para definir los estilos de TikZ?.

Respuesta2

Creo que matrixla biblioteca es redundante aquí (aunque estoy abusando de ella continuamente). El uso sencillo también es posible y (en mi opinión) más conveniente. La positioningbiblioteca se utiliza de todos modos, por lo que podemos seguir confiando en ella.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}
\begin{tikzpicture}[
    block/.style={rectangle, draw, 
        minimum width=5em, text centered, rounded corners, minimum
        height=4em,text width=5em}
    ]
\node (l1) at (0,2) {label 1};
\node (l2) at (0,0) {label 2};
\node[right = 2.5cm of l1,block] (n1) {Node 1};
\node[right = of n1,block] (n2) {Node 2};
\node[right = 1cm of l2,block] (n3) {Node 3};
\node[right = of n3,block] (n4) {Node 4};
\node[block,right=of n4] (n5) {node 5};
\draw (n1) -- (n4); % this fails not :)
\end{tikzpicture}
\end{document}

Tenga en cuenta que puede realizar un seguimiento del posicionamiento individual y la configuración predeterminada por node distanceopción y <direction> = x cm of nodenametal como necesitaría hacerlo row sepcuando column seputilice matrices.

ingrese la descripción de la imagen aquí


EDITARComo comentó Altermundus, puedes apilar tus filas centrándote en una cuadrícula de coordenadas predefinida

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{positioning}
\begin{document}

\begin{tikzpicture}[
    block/.style={rectangle, draw, text centered, rounded corners, minimum height=4em}
    ]
\foreach \x in {0,...,2} \node[circle,inner sep=1mm,fill] (cent\x) at (2,2*\x) {}; 
%The center goes in between
\node[right=of cent0,block] (n1) {A very wide node 1};
\node[left =of cent0,block] (n2) {2};
%The center hits the node
\node[block] at (cent1) (n4) {node 4};
\node[block,left =of n4] (n3) {Also a quite wide node 3};
\node[block,right=of n4] (n5) {5};
\draw (n1) -- (n4); % this fails not :)
%This uses eyeballing after compiling. Choose the widest and adjust.Can be absolute too.
\node[left= of n3] (l2) {label 2};
\node (l1) at (l2 |- cent0){label 1};
\node (l3) at (l2 |- cent2){label 3};
\end{tikzpicture}
\end{document}

ingrese la descripción de la imagen aquí

Respuesta3

Puedes evitar las imágenes anidadas.

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{matrix}
\usetikzlibrary{positioning}
\begin{document}

\begin{tikzpicture}[auto, semithick,remember picture,
    block/.style={rectangle, draw, 
        minimum width=5em, text centered, rounded corners, minimum
        height=4em,text width=5em}
    ]

    \matrix[matrix of nodes, row sep = 2em,
    nodes={anchor=center}
    ] (mx2){
        % First row:
        label1
        & 
          \node[block,right=1em,anchor=west](n1){node1}; 
          \node[block, right=of n1](n2){node2};         
        \\
        % Second row:
        label2
        &
            \node[block] (n3) {node 3};
            \node[block] (n4) [right=of n3] {node 4};
            \node[block] (n5) [right=of n4]  {node 5};
        \\
    };
    \draw (n1) -- (n4); % this fails
\end{tikzpicture}

\end{document} 

ingrese la descripción de la imagen aquí

información relacionada