![Почему при использовании pgfplots я получаю «неопределенную управляющую последовательность» при попытке использовать переменную foreach в качестве параметра для addplot?](https://rvso.com/image/254718/%D0%9F%D0%BE%D1%87%D0%B5%D0%BC%D1%83%20%D0%BF%D1%80%D0%B8%20%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B8%20pgfplots%20%D1%8F%20%D0%BF%D0%BE%D0%BB%D1%83%D1%87%D0%B0%D1%8E%20%C2%AB%D0%BD%D0%B5%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%BD%D1%83%D1%8E%20%D1%83%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D1%8F%D1%8E%D1%89%D1%83%D1%8E%20%D0%BF%D0%BE%D1%81%D0%BB%D0%B5%D0%B4%D0%BE%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D1%8C%D0%BD%D0%BE%D1%81%D1%82%D1%8C%C2%BB%20%D0%BF%D1%80%D0%B8%20%D0%BF%D0%BE%D0%BF%D1%8B%D1%82%D0%BA%D0%B5%20%D0%B8%D1%81%D0%BF%D0%BE%D0%BB%D1%8C%D0%B7%D0%BE%D0%B2%D0%B0%D1%82%D1%8C%20%D0%BF%D0%B5%D1%80%D0%B5%D0%BC%D0%B5%D0%BD%D0%BD%D1%83%D1%8E%20foreach%20%D0%B2%20%D0%BA%D0%B0%D1%87%D0%B5%D1%81%D1%82%D0%B2%D0%B5%20%D0%BF%D0%B0%D1%80%D0%B0%D0%BC%D0%B5%D1%82%D1%80%D0%B0%20%D0%B4%D0%BB%D1%8F%20addplot%3F.png)
Поскольку у меня есть несколько графиков с погрешностями, я хотел бы немного сместить погрешности, чтобы сделать общий график более читаемым. Однако, когда я пытаюсь сделать это, используя переменную a \foreach
в качестве величины сдвига, я получаю ошибку "неопределенная управляющая последовательность".
\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}
(Документ не компилируется, если я раскомментирую хотя бы один из двух комментариев.)
Что здесь не так?
РЕДАКТИРОВАТЬ: Добавлена еще одна переменная в \foreach
. В моем реальном варианте использования она будет содержать имя файла для построения графика данных или метку для использования в качестве кривой.
решение1
Проблема заключается в проблеме макрорасширения: \y
переменная вычисляется позже, но в этот «поздний» момент цикл уже завершен и \y
не определен.
Как уже упоминалось, \pgfplotsinvokeforeach
имеет только один аргумент цикла (обратите внимание, что \pgfplotsforeachungrouped
поддерживает два аргумента, но здесь это не помогает).
Вот один подход, который делаетвсегдаработают, независимо от того, насколько сложны ваши циклы:
\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}
Я ввел artifical \edef
, который охватывает все тело цикла. Это \edef
означает «расширенное определение»: оно определяется \temp
как полностью развернутый результат всего, что находится внутри фигурных скобок. Это расширится \y
до текущего значения цикла. К сожалению, оно также (попытается) расшириться \addplot
— что невозможно. Чтобы избежать этого расширения, я написал примитив TeX \noexpand
перед \addplot
.
Наконец, \temp
содержит тело циклабезлюбые ссылки на \y
или \x
. Мы можем просто выполнить его, записав \temp
в тело цикла. Это делает работу.
Для любопытных: список координат можно оставить за пределами \edef
:
\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}
это также работает, потому что TeX работает посредством расширения — как только он «выполняется» \temp
, он больше ничего не знает о том, что он находится «внутри», \temp
и будет просто читать вперед.
Видетьhttp://pgfplots.sourceforge.net/TeX-programming-notes.pdfдля подробностей