使用 \pgfplotstableforeachcolumn 生成 tikz 矩阵(或表格)时出现问题

使用 \pgfplotstableforeachcolumn 生成 tikz 矩阵(或表格)时出现问题

我正在尝试tikz从表格文件中的数据生成图片并读取它pgfplotstable(并且我没有直接绘制数据,因此我不能pgfplots直接使用)。

第一步是能够遍历表的元素来生成 tikz 矩阵,但我遇到了无法解释的问题。

这是一个简单的例子:

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

它给出了如下神秘的错误信息:

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

将 tikz 矩阵换成表格会产生相同的错误。问题似乎来自命令\\,因为如果我删除它,使其仅生成一个单元格,循环就会起作用。尝试生成表格而不是 tikz 矩阵的行时也会出现同样的问题。请注意,使用其他迭代方法(如宏)可以\foreach在矩阵(或表格)内工作,但我无法对表格列进行迭代。

我错过了什么?

答案1

不幸的是,任何类型的 TeX 循环构造在\begin{tabular}或其他制表环境中,例如\matrix 不工作。这是 TeX 的一个限制,它对于所见和所执行的内容有自己的理解。

您需要做的是编写一些代码,生成类似以下片段的内容,然后指示 TeX 处理它,而无需中间进一步的可执行指令:

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

我选择上面的公式是因为它类似于下面显示的代码生成的输出——但任何其他代码生成器都必须产生相同(或类似)的输出。请注意

  • \bgroup与 相同,{只是它可以被附加到某些“stringbuilder”中,尽管}缺少关联(即,\bgroup是不平衡的形式{
  • \pgfmatrixnextcell如果代码是在某些宏中生成的,则 PGF 手册会提供此功能\matrix。由于某些技术原因,矩阵代码不支持&这种情况(有关详细信息,请参阅 PGF 手册)。

我希望它会更简单,但 TeX 远非简单(当然这就是你在这里问这个问题的原因)。

该包pgfplotstable只不过是一个复杂的 CSV 数据代码生成器。以下代码片段自定义了其输出,以便生成一个 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}

在此处输入图片描述

请注意,我已自由输出整个 CSV 输入表,即使您的尝试仅考虑了其中的一部分。如果我的解决方案看起来是正确的方向,您可以在中找到许多键来自定义列名称、输出列的选择、输出行等pgfplotstable

我认为这是一个相对优雅的解决方案,尽管 - 我敢打赌 - 它会让你或本网站的其他访问者疑惑“我怎么可能用一段简单的代码做同样的事情”。答案是:要么通过对 TeX 宏语言的更多控制(“TeX 扩展控制”,见我应该从哪里开始 LaTeX 编程?)或者通过 Lua 代码来汇编语句并输出可执行的 TeX 代码。但这超出了我的回答范围。

相关内容