由於我有多個帶有誤差線的圖,因此我想稍微移動誤差線以使整體圖更具可讀性。但是,當我嘗試使用變數 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}
我引入了一種\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欲了解詳情