Problemas ao gerar uma matriz tikz (ou tabular) usando \pgfplotstableforeachcolumn

Problemas ao gerar uma matriz tikz (ou tabular) usando \pgfplotstableforeachcolumn

Estou tentando gerar uma tikzimagem a partir de dados em um arquivo de tabela, lendo-os pgfplotstable(e não estou plotando os dados diretamente, então não posso usar pgfplotsdiretamente).

O primeiro passo é poder iterar pelos elementos da tabela para gerar uma matriz tikz, mas tenho problemas que não consigo explicar.

Aqui está um exemplo 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}

que fornece mensagens de erro enigmáticas como:

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

Trocar a matriz tikz por uma tabular produz os mesmos erros. Parece que o problema vem do \\comando, pois se eu retirá-lo, fazendo com que ele gere apenas uma célula, o loop funciona. O mesmo problema acontece também ao tentar gerar linhas de uma matriz tabular em vez de uma matriz tikz. Observe que o uso de outros métodos de iteração, como a \foreachmacro, funciona dentro da matriz (ou tabular), mas não tenho como iterar nas colunas das tabelas.

o que estou perdendo?

Responder1

Infelizmente, qualquer tipo de construção de loop TeX dentro \begin{tabular}ou em outros ambientes tabulados como\matrix não funciona. Esta é uma limitação do TeX que tem seu próprio entendimento do que vê e do que executa.

O que você precisa fazer é escrever algum código que gere algo como o seguinte recorte e então instrua o TeX a processá-lo sem mais instruções executáveis ​​no meio:

\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 ;%

Eu escolhi a formulação acima porque ela se assemelha à saída da minha geração de código mostrada abaixo - mas qualquer outro gerador de código terá que resultar na mesma saída (ou semelhante). Observe que

  • \bgroupé o mesmo, {exceto que pode ser anexado a algum "stringbuilder", embora o associado }esteja faltando (ou seja, \bgroupé uma forma desequilibrada de {)
  • \pgfmatrixnextcellé algo que o manual do PGF fornece se \matrixo código for gerado em alguma macro. Por alguma razão técnica, o código da matriz não é compatível &se for esse o caso (consulte o manual do PGF para obter detalhes).

Eu gostaria que fosse mais simples, mas o TeX está longe de ser simples (é por isso que você fez essa pergunta aqui, é claro).

O pacote pgfplotstablenada mais é do que um sofisticado gerador de código para dados CSV. O trecho a seguir personaliza sua saída de forma que gere uma matriz PGF de nós:

\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}

insira a descrição da imagem aqui

Observe que tomei a liberdade de gerar toda a tabela de entrada CSV, mesmo que sua tentativa considere apenas partes dela. Se minha solução parecer ser a direção certa, você poderá encontrar muitas chaves para personalizar os nomes das colunas, a seleção das colunas de saída, as linhas de saída, pgfplotstableetc.

Suponho que esta seja uma solução relativamente elegante, embora - aposto - deixe você ou algum outro visitante deste site se perguntando "como eu poderia fazer o mesmo com um simples pedaço de código". A resposta é: seja por meio de mais controle da linguagem macro TeX ("controle de expansão TeX", vejaPor onde começo a programação LaTeX?) ou por meio do código Lua que monta as instruções e gera o código TeX executável. Mas isso está além da minha resposta.

informação relacionada