我想使用类似以下的方法创建在文档顶部定义的一些数据点的图:
\newcommand{\test}{{3,4,2,5}}
为了做到这一点,我创建了一个宏来解析这些值并将它们转换成类似的东西:
(0,3) (1,4) (2,2) (3,5)
不幸的是,如果我使用宏来生成它,我会得到
Incomplete \ifx; all text was ignored after line 33.
第 33 行要求 pgfplot 将坐标添加到图形中(参见下面的完整文件)。
另一方面,如果我直接创建坐标:
\newcommand{\tester}{ { (1.0,3) (2.0,4) (3.0,2) (4.0,5) } }
...
\addplot coordinates { {\tester} };
一切进展顺利。另一方面,如果我使用宏:
\newcommand{\tester}{ \makeCoords{\test} }
...
\addplot coordinates { {\tester} };
然后我得到了编译错误。请注意,\tester
创建坐标时我可以打印出来,一切看起来都很好。
下面是示例测试代码。通过切换第 18 行和第 19 行的注释,您可以在查看程序是否正常运行和是否出现问题之间来回切换。有什么想法可以解决这个问题吗?
\documentclass{article}
\usepackage{pgfplots}
\begin{document}
\newcommand{\test}{{3,4,2,5}}
\newcommand{\pgfval}[1]{\pgfmathparse{#1}\pgfmathresult}
\newcommand{\makeCoords}[2][0]{\foreach \tmp in #2{
\foreach \testVal[count=\i] in \tmp{
(\pgfval{\i+#1},\testVal)
}
}%foreach
}%newcommand
Test is \test
\newcommand{\tester}{\makeCoords{\test}}
% \newcommand{\tester}{ { (1.0,3) (2.0,4) (3.0,2) (4.0,5) } }
tester is \tester % Print out for debugging
\begin{figure}
\begin{tikzpicture}
\begin{axis}[
xlabel={timestep},
ylabel={Location(x)},
xmin=0, xmax=6,
ymajorgrids=true,
grid style = dashed
]
\addplot coordinates { {\tester} };
\end{axis}
\end{tikzpicture}
\end{figure}
\end{document}
答案1
使用表格可能pgfplotstable
会有效。从这样的表格中绘制列并计算x expr
绘图的 x 值当然很简单。请参见下面的示例。
可以使用 访问表中的各个值\pgfplotstablegetelem{<row>}{<column>}\of\tablename
,并将结果保存在 中\pgfplotsretval
。
\documentclass{article}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.18}
\begin{document}
\pgfplotstableread{
3
4
2
5
}\test
You can print the table:
% the option hides the header row
\pgfplotstabletypeset[every head row/.style={output empty row}]\test
% indexing in tables starts at zero, so this is the third row, first column
\pgfplotstablegetelem{2}{[index]0}\of\test
\pgfmathsetmacro\foo{\pgfplotsretval}
Now the third element in the table is \foo.
\begin{tikzpicture}
\begin{axis}[
xlabel={timestep},
ylabel={Location(x)},
xmin=0, xmax=6,
ymajorgrids=true,
grid style = dashed
]
\addplot table[x expr=\coordindex+1,y index=0] {\test};
\end{axis}
\end{tikzpicture}
\end{document}
答案2
作为练习,这里有一个解决方案functional
包裹:
\documentclass{article}
\usepackage{pgfplots}
\usepackage{functional}
\begin{document}
\newcommand{\test}{3,4,2,5}
\IgnoreSpacesOn
\PrgNewFunction \MakeCoords {M} {
\ClistClear \lTmpaClist
\IntZero \lTmpaInt
\ClistVarMapInline #1 {
\IntIncr \lTmpaInt
\ClistPutRight \lTmpaClist {\Expand{{(\OnlyValue\lTmpaInt,##1)}}}
}
\TlSet #1 {\ClistVarJoin \lTmpaClist {~}}
}
\IgnoreSpacesOff
Test is \test
\MakeCoords \test
Test is \test
\begin{figure}
\begin{tikzpicture}
\begin{axis}[
xlabel={timestep},
ylabel={Location(x)},
xmin=0, xmax=6,
ymajorgrids=true,
grid style = dashed
]
\addplot coordinates { {\test} };
\end{axis}
\end{tikzpicture}
\end{figure}
\end{document}
答案3
您可以使用\foreach
-loop 来收集临时宏中的内容。循环完成后,使用临时宏执行临时宏扩展的任何操作。例如,操作可以是定义\tester
保存坐标的宏的命令。
\DefineCoordsMacro[⟨x-shift of coordinates⟩]%
{⟨definition-command for defining macro holding list of coordinates⟩}%
{⟨braced comma-list or macro holding unbraced comma-list of y-values of coordinates⟩}
\documentclass{article}
\usepackage{pgfplots}
\newcommand\Scratchmacro{}
\newcommand\Exchange[2]{#2#1}
\makeatletter
\newcommand{\DefineCoordsMacro}[3][0]{%
\begingroup
\gdef\Scratchmacro{ }%
\foreach \testVal[count=\i] in #3{%
\pgfmathparse{\i+#1}%
\xdef\Scratchmacro{%
\unexpanded\expandafter{\Scratchmacro}%
(%
\unexpanded\expandafter{\pgfmathresult}%
,%
\unexpanded\expandafter{\testVal}%
) %
}%
}%foreach
\expandafter\Exchange\expandafter{\expandafter{\Scratchmacro}}{\endgroup#2}%
}%newcommand
\makeatother
\begin{document}
\newcommand{\test}{3,4,2,5}
\DefineCoordsMacro{\newcommand\tester}{\test}
%\DefineCoordsMacro[2]{\renewcommand\tester}{{3,4,2,5}}
% Print out for debugging:
\noindent
The meaning of the macro \texttt{\string\test} is:\\ \texttt{\meaning\test}
\noindent
The meaning of the macro \texttt{\string\tester} is:\\ \texttt{\meaning\tester}
\begin{figure}
\noindent
\begin{tikzpicture}
\begin{axis}[
xlabel={timestep},
ylabel={Location(x)},
xmin=0, xmax=6,
ymajorgrids=true,
grid style = dashed
]
\addplot coordinates { {\tester} };
\end{axis}
\end{tikzpicture}
\end{figure}
\end{document}