Segunda versión

Segunda versión

Tengo dos diagramas (se supone que ambos son iguales), uno con comandos explícitos de dibujo y nodo, el otro con foreachbucles. Obviamente, no entiendo los bucles foreach, ya que solo puedo hacer funcionar uno. Seguí el tutorial de tikz, pero rápidamente se me pasó por la cabeza. Estoy tratando de entender la lógica de tikz mediante prueba y error, pero me desanimé un poco después de intentar cosas aparentemente simples. Necesito ayuda con los demás. Pido un empujón en la dirección correcta sobre cómo debo hacer esto. ¿Cómo necesitaría diseñar mis bucles para acortar el código del primer diagrama? El segundo no funciona cuando las líneas están comentadas.

\documentclass{article}
\usepackage[margin=20mm]{geometry}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
\draw (0,0) rectangle +(10.5,8);
\draw (0.1,0.1) rectangle +(10.3,7.8);
\foreach \x in {1.5,4,6.5,9}
    \foreach \y in {1.5,4,6.5}
        \draw (\x,\y) circle (1);

\node at (1.5,1.5) {PreA30};
\node at (1.5,4) {PreB30};
\node at (1.5,6.5) {PreC30};

\node at (4,1.5) {PreA50};
\node at (4,4) {PreB50};
\node at (4,6.5) {PreC50};

\node at (6.5,1.5) {PreA70};
\node at (6.5,4) {PreB70};
\node at (6.5,6.5) {PreC70};

\node at (9,1.5) {PreA90};
\node at (9,4) {PreB90};
\node at (9,6.5) {PreC90};

\node at (1.5,-.5) {30\%};
\node at (4,-.5) {50\%};
\node at (6.5,-.5) {70\%};
\node at (9,-.5) {90\%};
\node at (-.5,1.5) {A};
\node at (-.5,4) {B};
\node at (-.5,6.5) {C};
\end{tikzpicture}

\begin{tikzpicture}
\draw (0,0) rectangle +(10.5,8);
\draw (0.1,0.1) rectangle +(10.3,7.8);

\foreach \x in {1.5,4,6.5,9}
    \foreach \y in {1.5,4,6.5}
        \draw (\x,\y) circle (1);

% the next block actually compiles, but the result is quite alarming
% I tried a different order, but that doesn't seem to matter at all
%\foreach \x in {1.5,4,6.5,9}
%   \foreach \y in {1.5,4,6.5}
%       \foreach \sam in {A,B,C}
%           \foreach \perc in {30,50,70,90}
%               \node at (\x,\y) {Pre\sam\perc};
%
%\foreach \x in {1.5,4,6.5,9}
%   \foreach \perc in {30,50,70,90}
%       \node at (\x,-.5) {\perc\%};
%
%\foreach \y in {1.5,4,6.5}
%   \foreach \sam in {A,B,C}
%       \node at {-.5,\y} {\sam};
\end{tikzpicture}

\end{document}

Con la respuesta de las marmotas, obtenemos lo que se muestra en la siguiente imagen. El primer diagrama es lo que se desea. El segundo diagrama tiene superposiciones de texto en todos los nodos. Sé que esto probablemente tenga más que ver con la lógica que con LaTeX, pero aún así, no puedo entender el diseño correcto de los bucles for. efecto deseado y no deseado

Respuesta1

Tienes cuatro bucles anidados, mientras que solo quieres dos, pero necesitas tener más de una variable de bucle. Eso se puede hacer con, por ejemplo

\foreach \x/\perc in {1.5/30,4/50,6.5/70,9/90}

es decir, cada elemento de la lista de variables contiene dos valores, separados por /.

Respecto a tu código original, los bucles funcionan bien, el único problema es que los has usado \node at {-.5,\y} {\sam};en lugar \node at (-.5,\y) {\sam};del final. (Llaves en lugar de paréntesis en las coordenadas). Al solucionar el problema de sobreimpresión, porque por cada par de valores \x/ \y, imprime 12 nodos: tres letras diferentes (A, B, C) y cuatro números diferentes (30, 50 , 70, 90), dan 12 combinaciones.

\documentclass{article}
\usepackage[margin=20mm]{geometry}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
\draw (0,0) rectangle +(10.5,8);
\draw (0.1,0.1) rectangle +(10.3,7.8);
\foreach \x in {1.5,4,6.5,9}
    \foreach \y in {1.5,4,6.5}
        \draw (\x,\y) circle (1);

\node at (1.5,1.5) {PreA30};
\node at (1.5,4) {PreB30};
\node at (1.5,6.5) {PreC30};

\node at (4,1.5) {PreA50};
\node at (4,4) {PreB50};
\node at (4,6.5) {PreC50};

\node at (6.5,1.5) {PreA70};
\node at (6.5,4) {PreB70};
\node at (6.5,6.5) {PreC70};

\node at (9,1.5) {PreA90};
\node at (9,4) {PreB90};
\node at (9,6.5) {PreC90};

\node at (1.5,-.5) {30\%};
\node at (4,-.5) {50\%};
\node at (6.5,-.5) {70\%};
\node at (9,-.5) {90\%};
\node at (-.5,1.5) {A};
\node at (-.5,4) {B};
\node at (-.5,6.5) {C};
\end{tikzpicture}

\begin{tikzpicture}
\draw (0,0) rectangle +(10.5,8);
\draw (0.1,0.1) rectangle +(10.3,7.8);

\foreach \x/\perc in {1.5/30,4/50,6.5/70,9/90}
   { % here you need to use braces, because there is more than one thing in the loop
   \node at (\x,-0.5) {\perc\%};
   \foreach \y/\sam in {1.5/A,4/B,6.5/C}
       {
       \draw (\x,\y) circle (1);
       \node at (\x,\y) {Pre\sam\perc};
       }
   }

% second loop for y-labels
\foreach \y/\sam in {1.5/A,4/B,6.5/C}
   \node at (-0.5,\y) {\sam};

\end{tikzpicture}
\end{document}

ingrese la descripción de la imagen aquí

Segunda versión

Hay más opciones disponibles para \foreach, como se describe en el capítulo 83 enel manual. Para un caso como este con nodos espaciados regularmente, podría tener sentido utilizar la countopción, que proporciona un contador para la variable del bucle. Y además, puedes utilizarlo evaluatepara hacer cálculos.

De esta manera, puede tener solo una variable de bucle para cada uno de los bucles y calcular las coordenadas en función de la iteración en la que se encuentre el bucle. La salida es la anterior.

\documentclass{article}
\usepackage[margin=20mm]{geometry}
\usepackage{tikz}
\usetikzlibrary{fit, backgrounds}
\begin{document}

\begin{tikzpicture}

\foreach [count=\i, evaluate={\x=\i*2.5}] \perc in {30,50,70,90}
   { % here you need to use braces, because there is more than one thing in the loop
   \foreach [count=\j, evaluate={\y=\j*2.5}] \sam in {A,B,C}
       {
       \node [circle,draw,minimum size=2cm] (\sam\perc) at (\x,\y) {Pre\sam\perc};
       \ifnum \i=1
         \node [left=5mm] at (\sam30.west) {\sam};
       \fi
       } % inner loop ends here
   % so this node is only in outer loop
   \node [below=5mm] at (A\perc.south) {\perc\%};
   }

\begin{scope}[on background layer]
  % fit both around same nodes, with different inner sep
  \node[draw,fit=(A30)(C90),inner sep=3mm, fill=blue!20] (frame) {}; % outer frame, larger inner sep
  \node[draw,fit=(A30)(C90),inner sep=2mm, fill=red!20] (frame) {}; % inner frame, smaller inner sep
\end{scope}
\end{tikzpicture}
\end{document}

como arriba con marco de fondo relleno

Respuesta2

Sé que esta pregunta es sobre foreach, pero si alguien tiene problemas para entender foreachel uso, es fácil reproducir este diagrama con matrixayuda:

\documentclass[tikz,border=2mm]{standalone} 
\usetikzlibrary{positioning, matrix, fit}

\begin{document}
\begin{tikzpicture}

\matrix[matrix of nodes,
            nodes={anchor=center, 
                circle, draw, minimum size=2cm},
            column 1/.style={%
                nodes={rectangle, minimum size=0pt, draw=none}},
            row 4/.style={%
                nodes={rectangle, minimum size=0pt, draw=none}},
            column sep=5mm, row sep=5mm]
(top)
{
C & PreC30 & PreC50 & PreC70 & PreC90 \\
B & PreB30 & PreB50 & PreB70 & PreB90 \\
A & PreA30 & PreA50 & PreA70 & PreA90 \\
  & 30\% & 50\% & 70\% & 90\% \\
};
\node[draw, double, fit=(top-1-2) (top-3-5), inner sep=3mm] {};
\end{tikzpicture}
\end{document}

ingrese la descripción de la imagen aquí

Respuesta3

Si usa los \foreachbucles, debe colocar todo lo que debería estar dentro del bucle en un grupo, es decir, rodearlo con {y }a menos que tenga solo un comando/grupo en el bucle. Aplicar esto a su código produce

\documentclass{article}
\usepackage[margin=20mm]{geometry}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
\draw (0,0) rectangle +(10.5,8);
\draw (0.1,0.1) rectangle +(10.3,7.8);
\foreach \x in {1.5,4,6.5,9}
    \foreach \y in {1.5,4,6.5}
        \draw (\x,\y) circle (1);

\node at (1.5,1.5) {PreA30};
\node at (1.5,4) {PreB30};
\node at (1.5,6.5) {PreC30};

\node at (4,1.5) {PreA50};
\node at (4,4) {PreB50};
\node at (4,6.5) {PreC50};

\node at (6.5,1.5) {PreA70};
\node at (6.5,4) {PreB70};
\node at (6.5,6.5) {PreC70};

\node at (9,1.5) {PreA90};
\node at (9,4) {PreB90};
\node at (9,6.5) {PreC90};

\node at (1.5,-.5) {30\%};
\node at (4,-.5) {50\%};
\node at (6.5,-.5) {70\%};
\node at (9,-.5) {90\%};
\node at (-.5,1.5) {A};
\node at (-.5,4) {B};
\node at (-.5,6.5) {C};
\end{tikzpicture}

\begin{tikzpicture}
\draw (0,0) rectangle +(10.5,8);
\draw (0.1,0.1) rectangle +(10.3,7.8);

\foreach \x in {1.5,4,6.5,9}
    {\foreach \y in {1.5,4,6.5}
        \draw (\x,\y) circle (1);}

% the next block actually compiles, but the result is quite alarming
% I tried a different order, but that doesn't seem to matter at all
\foreach \x in {1.5,4,6.5,9}
  {\foreach \y in {1.5,4,6.5}
      \foreach \sam in {A,B,C}
          {\foreach \perc in {30,50,70,90}
              \node at (\x,\y) {Pre\sam\perc};}}

\foreach \x in {1.5,4,6.5,9}
  {\foreach \perc in {30,50,70,90}
      \node at (\x,-.5) {\perc\%};}

\foreach \y in {1.5,4,6.5}
  {\foreach \sam in {A,B,C}
      \node at (-.5,\y) {\sam};}
\end{tikzpicture}

\end{document}

El código te proporciona ahora lo que creo que querías obtener.

información relacionada