使用 \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 對它所看到的內容和執行的內容有自己的理解。

您需要做的是編寫一些程式碼,產生類似以下片段的內容,然後指示 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\matrix如果程式碼是在某些巨集中產生的,PGF 手冊會提供這些內容。由於某些技術原因,矩陣代碼不支援&這種情況(請參閱 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 程式碼。但這超出了我的回答範圍。

相關內容