Probleme beim Generieren einer Tikz-Matrix (oder einer Tabelle) mit \pgfplotstableforeachcolumn

Probleme beim Generieren einer Tikz-Matrix (oder einer Tabelle) mit \pgfplotstableforeachcolumn

Ich versuche, tikzaus den Daten in einer Tabellendatei ein Bild zu generieren, indem ich sie durchlese pgfplotstable(und ich stelle die Daten nicht direkt dar, sodass ich sie nicht pgfplotsdirekt verwenden kann).

Der erste Schritt besteht darin, die Elemente der Tabelle durchlaufen zu können, um eine Tikz-Matrix zu generieren, aber ich habe Probleme, die ich nicht erklären kann.

Hier ist ein Minimalbeispiel:

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

das kryptische Fehlermeldungen ausgibt wie:

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

Das Ersetzen der Tikz-Matrix durch eine tabellarische Matrix führt zu denselben Fehlern. Das Problem scheint beim \\Befehl zu liegen, denn wenn ich ihn entferne und nur eine Zelle erzeuge, funktioniert die Schleife. Dasselbe Problem tritt auch beim Versuch auf, Zeilen einer tabellarischen anstelle einer Tikz-Matrix zu erzeugen. Beachten Sie, dass die Verwendung anderer Iterationsmethoden, wie z. B. des \foreachMakros, innerhalb der Matrix (oder tabellarisch) funktioniert, ich dann aber keine Möglichkeit habe, über die Tabellenspalten zu iterieren.

Was vermisse ich?

Antwort1

Leider ist jede Art von TeX-Schleifenkonstrukten innerhalb \begin{tabular}oder anderer tabellarischer Umgebungen wie\matrix arbeite nicht. Dies ist eine Einschränkung von TeX, das sein eigenes Verständnis davon hat, was es sieht und was es ausführt.

Sie müssen Code schreiben, der etwa den folgenden Ausschnitt erzeugt und dann TeX anweist, ihn ohne weitere ausführbare Anweisungen dazwischen zu verarbeiten:

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

Ich habe die obige Formulierung gewählt, da sie der Ausgabe meiner unten gezeigten Codegenerierung ähnelt – aber jeder andere Codegenerator muss dieselbe (oder eine ähnliche) Ausgabe liefern. Beachten Sie, dass

  • \bgroupist dasselbe wie, {außer dass es in einen „Stringbuilder“ angehängt werden kann, obwohl das zugehörige }fehlt (d. h. es \bgroupist eine unsymmetrische Form von {).
  • \pgfmatrixnextcellist etwas, das das PGF-Handbuch bereitstellt, wenn \matrixCode in einem Makro generiert wird. Aus technischen Gründen unterstützt der Matrixcode &dies in diesem Fall nicht (weitere Einzelheiten finden Sie im PGF-Handbuch).

Ich wünschte, es wäre einfacher, aber TeX ist alles andere als einfach (weshalb Sie diese Frage natürlich hier gestellt haben).

Das Paket pgfplotstableist nichts anderes als ein ausgeklügelter Codegenerator für CSV-Daten. Der folgende Codeausschnitt passt seine Ausgabe so an, dass er eine PGF-Matrix von Knoten erzeugt:

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

Bildbeschreibung hier eingeben

Beachten Sie, dass ich mir die Freiheit genommen habe, die gesamte CSV-Eingabetabelle auszugeben, auch wenn Ihr Versuch nur Teile davon berücksichtigt. Wenn Ihnen meine Lösung in die richtige Richtung zu gehen scheint, finden Sie in viele Schlüssel zum Anpassen der Spaltennamen, der Auswahl der Ausgabespalten, der Ausgabezeilen pgfplotstableusw.

Ich nehme an, dass dies eine relativ elegante Lösung ist, obwohl - ich wette - Sie oder ein anderer Besucher dieser Site sich fragen wird, "wie ich das Gleiche mit einem einfachen Stück Code erreichen könnte". Die Antwort lautet: entweder durch mehr Kontrolle der TeX-Makrosprache ("TeX-Erweiterungskontrolle", sieheWo beginne ich mit der LaTeX-Programmierung?) oder mittels Lua-Code, der die Anweisungen zusammensetzt und ausführbaren TeX-Code ausspuckt. Aber das geht über meine Antwort hinaus.

verwandte Informationen