Warum erhalte ich bei der Verwendung von pgfplots die Meldung „undefinierte Steuersequenz“, wenn ich versuche, eine Foreach-Variable als Parameter für Addplot zu verwenden?

Warum erhalte ich bei der Verwendung von pgfplots die Meldung „undefinierte Steuersequenz“, wenn ich versuche, eine Foreach-Variable als Parameter für Addplot zu verwenden?

Da ich mehrere Diagramme mit Fehlerbalken habe, möchte ich die Fehlerbalken leicht verschieben, um das Gesamtdiagramm lesbarer zu machen. Wenn ich dies jedoch versuche und dabei die Variable a \foreachals Verschiebungsbetrag verwende, erhalte ich die Fehlermeldung „undefinierte Steuersequenz“.

\documentclass{article}

\usepackage{tikz}
\usepackage{pgfplots}

\begin{document}

\begin{tikzpicture}
\begin{axis}
\foreach \x/\y in {a/-1cm, b/0cm, c/1cm} {
    \addplot+ [
        %every error bar/.append style={xshift=\y},
        %every node/.style={xshift=\y},
        error bars/y dir=both,
        error bars/y explicit,
    ] coordinates {
        (0, 0) +- (0, 1)
        (1, 0) +- (0, 1)
        (2, 0) +- (0, 1)
    };
}
\end{axis}
\end{tikzpicture}

\end{document}

(Das Dokument wird nicht kompiliert, wenn ich einen der beiden Kommentare auskommentiere.)

Was ist hier los?

BEARBEITEN: Eine weitere Variable wurde hinzugefügt \foreach. In meinem tatsächlichen Anwendungsfall würde sie den Dateinamen enthalten, aus dem Daten dargestellt werden sollen, oder die für die Kurve zu verwendende Beschriftung.

Antwort1

Das Problem ist ein Problem mit der Makroerweiterung: Die \yVariable wird später ausgewertet – aber zu diesem „späteren“ Zeitpunkt ist die Schleife beendet und \yundefiniert.

Wie bereits erwähnt, \pgfplotsinvokeforeachhat es nur ein Schleifenargument (beachten Sie, dass \pgfplotsforeachungroupedzwei Argumente unterstützt werden, was hier jedoch nicht hilft).

Hier ist ein Ansatz, derstetsfunktionieren, egal wie kompliziert Ihre Schleifen sind:

\begin{tikzpicture}
\begin{axis}
\foreach \x/\y in {a/-1cm, b/0cm, c/1cm} {
    \edef\temp{
        \noexpand\addplot+ [
            every error bar/.append style={xshift=\y},
            every node/.style={xshift=\y},
            error bars/y dir=both,
            error bars/y explicit,
        ]
        coordinates {
        (0, 0) +- (0, 1)
        (1, 0) +- (0, 1)
        (2, 0) +- (0, 1)
        };
    }
    \temp
}
\end{axis}
\end{tikzpicture}

Ich habe einen künstlichen Code eingeführt \edef, der den gesamten Schleifenkörper abdeckt. Dies \edefbedeutet „erweiterte Definition“: Es wird \tempals das vollständig erweiterte Ergebnis von allem innerhalb der geschweiften Klammern definiert. Dies wird \yauf den aktuellen Schleifenwert erweitert. Leider wird es auch (versuchen) zu erweitern \addplot– was unmöglich ist. Um diese Erweiterung zu vermeiden, habe ich das TeX-Grundelement \noexpandvor geschrieben \addplot.

Schließlich \tempenthält der Schleifenkörperohnealle Verweise auf \yoder \x. Wir können es einfach ausführen, indem wir es \tempin den Schleifenkörper schreiben. Damit funktioniert es.


Nur für Neugierige: Sie könnten die Koordinatenliste auch außerhalb von \edef: belassen.

\begin{tikzpicture}
\begin{axis}
\foreach \x/\y in {a/-1cm, b/0cm, c/1cm} {
    \edef\temp{
        \noexpand\addplot+ [
            every error bar/.append style={xshift=\y},
            every node/.style={xshift=\y},
            error bars/y dir=both,
            error bars/y explicit,
        ]
    }
    \temp
        coordinates {
        (0, 0) +- (0, 1)
        (1, 0) +- (0, 1)
        (2, 0) +- (0, 1)
    };
}
\end{axis}
\end{tikzpicture}

dies funktioniert auch, weil TeX mit Expansion arbeitet - sobald es „ausgeführt“ wird \temp, weiß es nichts mehr davon, dass es sich „innerhalb“ von befindet \tempund liest einfach weiter.

Sehenhttp://pgfplots.sourceforge.net/TeX-programming-notes.pdffür Details

verwandte Informationen