![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?](https://rvso.com/image/254718/Warum%20erhalte%20ich%20bei%20der%20Verwendung%20von%20pgfplots%20die%20Meldung%20%E2%80%9Eundefinierte%20Steuersequenz%E2%80%9C%2C%20wenn%20ich%20versuche%2C%20eine%20Foreach-Variable%20als%20Parameter%20f%C3%BCr%20Addplot%20zu%20verwenden%3F.png)
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 \foreach
als 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 \y
Variable wird später ausgewertet – aber zu diesem „späteren“ Zeitpunkt ist die Schleife beendet und \y
undefiniert.
Wie bereits erwähnt, \pgfplotsinvokeforeach
hat es nur ein Schleifenargument (beachten Sie, dass \pgfplotsforeachungrouped
zwei 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 \edef
bedeutet „erweiterte Definition“: Es wird \temp
als das vollständig erweiterte Ergebnis von allem innerhalb der geschweiften Klammern definiert. Dies wird \y
auf 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 \noexpand
vor geschrieben \addplot
.
Schließlich \temp
enthält der Schleifenkörperohnealle Verweise auf \y
oder \x
. Wir können es einfach ausführen, indem wir es \temp
in 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 \temp
und liest einfach weiter.
Sehenhttp://pgfplots.sourceforge.net/TeX-programming-notes.pdffür Details