Problemas al generar una matriz tikz (o una tabular) usando \pgfplotstableforeachcolumn

Problemas al generar una matriz tikz (o una tabular) usando \pgfplotstableforeachcolumn

Estoy intentando generar una tikzimagen a partir de datos en un archivo de tabla, leyéndola pgfplotstable(y no estoy trazando los datos directamente, por lo que no puedo usarlos pgfplotsdirectamente).

El primer paso es poder iterar por los elementos de la tabla para generar una matriz tikz, pero tengo problemas que no puedo explicar.

Aquí hay un ejemplo mínimo:

\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplotstable}
\usepackage{filecontents}

\usetikzlibrary{matrix}

\begin{filecontents*}{file.table}
col1 col2 col3 col4 col5
   a    b    c    d    e
\end{filecontents*}

\begin{document}

\pgfplotstableread{file.table}\mytable

\begin{tikzpicture}
  \matrix (plots) [matrix of nodes] {
    \pgfplotstableforeachcolumn\mytable\as\col{%
      \col \\
    }
  };
\end{tikzpicture}

% This also doesn't work
% \begin{tabular}{c}
%   \pgfplotstableforeachcolumn\mytable\as\col{%
%     \col \\
%   }
% \end{tabular}

\end{document}

lo que genera mensajes de error crípticos como:

./mwe.tex:21: Undefined control sequence. [ }]
./mwe.tex:21: Missing number, treated as zero. [ }]

Cambiar la matriz tikz por una tabular produce los mismos errores. Parece que el problema viene del \\comando, porque si lo elimino haciendo que genere solo una celda, el bucle funciona. El mismo problema ocurre también al intentar generar filas de una matriz tabular en lugar de una matriz tikz. Tenga en cuenta que el uso de otros métodos de iteración, como la \foreachmacro, funciona dentro de la matriz (o tabular), pero no tengo ninguna forma de iterar sobre las columnas de las tablas.

¿Qué me estoy perdiendo?

Respuesta1

Desafortunadamente, cualquier tipo de construcción de bucle TeX dentro de \begin{tabular}u otros entornos tabulados como\matrix No funcionan. Esta es una limitación de TeX, que tiene su propia comprensión de lo que ve y lo que ejecuta.

Lo que debe hacer es escribir un código que genere algo como lo siguiente recortado y luego le indique a TeX que lo procese sin más instrucciones ejecutables intermedias:

\matrix (plots) [matrix of nodes] \bgroup %
col1\pgfmatrixnextcell col2\pgfmatrixnextcell col3\pgfmatrixnextcell col4\pgfmatrixnextcell col5\\%
a\pgfmatrixnextcell b\pgfmatrixnextcell c\pgfmatrixnextcell d\pgfmatrixnextcell e\\%
\egroup ;%

Elegí la formulación anterior porque se parece al resultado de mi generación de código que se muestra a continuación, pero cualquier otro generador de código tendrá que generar el mismo (o similar) resultado. Tenga en cuenta que

  • \bgroupes lo mismo {excepto que se puede agregar a algún "constructor de cadenas" aunque }falta el asociado (es decir, \bgroupes una forma desequilibrada de {)
  • \pgfmatrixnextcelles algo que proporciona el manual de PGF si \matrixse genera código en alguna macro. Por alguna razón técnica, el código de matriz no es compatible &si ese es el caso (consulte el manual de PGF para obtener más detalles).

Desearía que fuera más simple, pero TeX está lejos de ser simple (por eso, por supuesto, hiciste esta pregunta aquí).

El paquete pgfplotstableno es más que un sofisticado generador de código para datos CSV. El siguiente fragmento personaliza su salida de modo que genere una matriz de nodos PGF:

\documentclass{standalone}
\usepackage{tikz}
\usepackage{pgfplotstable}
\usepackage{filecontents}

\usetikzlibrary{matrix}

\begin{filecontents*}{file.table}
col1 col2 col3 col4 col5
   a    b    c    d    e
\end{filecontents*}

\begin{document}

\pgfplotstableread{file.table}\mytable

\begin{tikzpicture}
  \pgfplotstabletypeset[
    string type,
    skip coltypes=true,
    debug,
    %
    typeset cell/.code={%
        % this here is more-or-less the default implementation, but it
        % substitutes '&' by '\pgfmatrixnextcell':
        \ifnum\pgfplotstablecol=\pgfplotstablecols
            \pgfkeyssetvalue{/pgfplots/table/@cell content}{#1\\}%
        \else
            \pgfkeyssetvalue{/pgfplots/table/@cell content}{#1\pgfmatrixnextcell}%
        \fi
    },
    % '\bgroup' / '\egroup' = '{' / '}' except that it does not need to be balanced
    begin table={\matrix (plots) [matrix of nodes] \bgroup},
    end table={\egroup;},
  ]{\mytable}
\end{tikzpicture}

\end{document}

ingrese la descripción de la imagen aquí

Tenga en cuenta que me he tomado la libertad de generar la tabla de entrada CSV completa, aunque su intento solo considera partes de ella. Si mi solución parece ser la dirección correcta, puede encontrar muchas claves para personalizar los nombres de las columnas, la selección de columnas de salida, las filas de salida, pgfplotstableetc.

Supongo que esta es una solución relativamente elegante, aunque, apuesto, te deja a ti o a algún otro visitante de este sitio preguntándose "¿cómo podría hacer lo mismo con un simple fragmento de código?". La respuesta es: ya sea mediante un mayor control del lenguaje de macros TeX ("control de expansión TeX", ver¿Dónde empiezo a programar en LaTeX?) o mediante código Lua que ensambla las declaraciones y genera código TeX ejecutable. Pero eso está más allá de mi respuesta.

información relacionada