Estou tentando gerar uma tikz
imagem 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 pgfplots
diretamente).
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 \foreach
macro, 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\matrix
o 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 pgfplotstable
nada 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}
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, pgfplotstable
etc.
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.