在轴环境中扩展 \pgfplotsinvokeforeach 中的宏

在轴环境中扩展 \pgfplotsinvokeforeach 中的宏

我使用 \pgfplotsinvokeforeach 和 \pgfplotstablegetelem 从表中提取某些数据值,然后将其直接绘制到 pgfplots 轴上。从表中任何一行提取的数据用于在与时间 (m) 和高度 (h_Moon) 对应的坐标处绘制月相。

我的 MWE 如下。就目前情况而言,我认为存在与宏评估被推迟相关的问题。(例如参见此处)。编译结果只使用循环中的最后一项。我无法让循​​环使用表中的所有行,为每个行绘制一个月相。

\begin{filecontents*}{Tracking.txt}
m   A_Moon  h_Moon  k_Moon  i_Moon  chi_Moon
1   45.5814 -17.1705    0.0569126   152.396 110.821
2   58.0011 -9.82216    0.0547727   152.93  111.058
3   69.4323 -1.41611    0.052673    153.464 111.299
4   80.3212 7.64628 0.0506139   153.997 111.542
5   91.1983 17.0132 0.0485953   154.53  111.789
6   102.694 26.336  0.0466174   155.062 112.041
7   115.596 35.2012 0.0446804   155.594 112.296
\end{filecontents*}

\documentclass[]{article}

\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
xlabel={Time (hr)},
ylabel={Altitude ($^\circ$)},
xmin=0,
xmax=12,
ymin=-90,
ymax=90,
xtick={0,1,...,12},
ytick={-80,-60,...,80}
]

\pgfplotstableread{Tracking.txt}\Tracking;

\newlength{\moonsize}\setlength{\moonsize}{10pt}
\pgfplotsinvokeforeach {1,2,...,6} {
    \pgfplotstablegetelem{#1}{m}\of{\Tracking}\pgfmathsetmacro{\MoonFigurePointX}{\pgfplotsretval}
    \pgfplotstablegetelem{#1}{h_Moon}\of{\Tracking}\pgfmathsetmacro{\MoonFigurePointY}{\pgfplotsretval}
    \pgfplotstablegetelem{#1}{k_Moon}\of{\Tracking}\pgfmathsetmacro{\MoonFigureFraction}{\pgfplotsretval}
    \pgfplotstablegetelem{#1}{i_Moon}\of{\Tracking}\pgfmathsetmacro{\MoonFigurePhase}{\pgfplotsretval}
    \pgfplotstablegetelem{#1}{chi_Moon}\of{\Tracking}\pgfmathsetmacro{\MoonFigureAngle}{\pgfplotsretval}
    \begin{scope}[rotate around={\MoonFigureAngle+90:(axis cs:\MoonFigurePointX,\MoonFigurePointY)}]
        \pgfmathparse{(\MoonFigurePhase>=0)?1:0}\ifdim\pgfmathresult pt>0pt%
        \draw [fill=black!10] ++(axis cs:\MoonFigurePointX,\MoonFigurePointY) ++(0,-\moonsize) arc [start angle=-90,end angle=90,radius=\moonsize] arc [start angle=90,end angle=270,y radius=\moonsize,x radius={-\moonsize + \MoonFigureFraction*2*\moonsize}];
        \fi
        \pgfmathparse{(\MoonFigurePhase<0)?1:0}\ifdim\pgfmathresult pt>0pt%
        \draw [fill=black!10] ++(axis cs:\MoonFigurePointX,\MoonFigurePointY) ++(0,-\moonsize) arc [start angle=90,end angle=-90,radius=-\moonsize] arc [start angle=90,end angle=270,y radius=\moonsize,x radius={\moonsize - \MoonFigureFraction*2*\moonsize}];
        \fi
    \end{scope}
\draw (axis cs:\MoonFigurePointX,\MoonFigurePointY) node [font=\scriptsize,below=0.7\moonsize] {\pgfmathparse{int(round(\MoonFigureFraction*1000))/10}\pgfmathprintnumber{\pgfmathresult}\%};

}

\end{axis}
\end{tikzpicture}
\end{document}

代码产生如下结果:

在此处输入图片描述

然而,我想要得到这个:

在此处输入图片描述

在上面的链接中,建议的解决方法是使用 \edef 显式扩展循环变量。我尝试过这种方法以及许多不同的方法,但它仍然只使用表中的最后一行。

此外,我并不完全相信宏扩展就是全部问题。例如,如果我将消息 (\MoonFigurePointX) 插入到循环中,我可以在日志中看到在循环的每次迭代中确实从表中读取了正确的值。

请注意,这只是一个更大问题的一个方面。还有其他事情没有出现在这个 MWE 中(并且不会直接影响我遇到的问题),这解释了为什么我直接在 pgfplots 轴上绘图,而从 MWE 来看,似乎没有理由使用轴。

最后,这是我的第一篇 tex.stackexchange 帖子(我通常可以通过 Google 和耐心解决 LaTeX 问题,但这次不行)。如果我没有正确遵守规则,或者您认为我可以改进我的问题,请告诉我,我会做出调整。

答案1

我设法找到了一个解决方案。我认为它不是很优雅,但它有效。

正如我猜测的那样,问题在于 (1) 宏扩展被推迟到循环完成后,以及 (2) 我对宏扩展的理解不够深入。

我已将月亮绘制代码移入,并找到了和与变量\newcommand\drawmoon[5]的有效组合,以包含扩展的宏。我还将循环中的使用替换为。\edef\noexpand\tmp\pgfmathsetmacro\edef

更新后的 MWE 如下:

\begin{filecontents*}{Tracking.txt}
m   A_Moon  h_Moon  k_Moon  i_Moon  chi_Moon
1   45.5814 -17.1705    0.0569126   152.396 110.821
2   58.0011 -9.82216    0.0547727   152.93  111.058
3   69.4323 -1.41611    0.052673    153.464 111.299
4   80.3212 7.64628 0.0506139   153.997 111.542
5   91.1983 17.0132 0.0485953   154.53  111.789
6   102.694 26.336  0.0466174   155.062 112.041
7   115.596 35.2012 0.0446804   155.594 112.296
\end{filecontents*}

\documentclass[]{article}

\usepackage{pgfplots}

\newlength{\moonsize}\setlength{\moonsize}{10pt}

\newcommand\drawmoon[5]{
    \edef\tmp{\noexpand\begin{scope}[rotate around={#5+90:(axis cs:#1,#2)}]}\tmp
    \pgfmathparse{(#4>=0)?1:0}\ifdim\pgfmathresult pt>0pt%
    \edef\tmp{\noexpand\draw [fill=black!10] ++(axis cs:#1,#2) ++(0,-\moonsize) arc [start angle=-90,end angle=90,radius=\moonsize] arc [start angle=90,end angle=270,y radius=\moonsize,x radius={-\moonsize + #3*2*\moonsize}];}\tmp
    \fi
    \pgfmathparse{(#4<0)?1:0}\ifdim\pgfmathresult pt>0pt%
    \edef\tmp{\noexpand\draw [fill=black!10] ++(axis cs:#1,#2) ++(0,-\moonsize) arc [start angle=90,end angle=-90,radius=-\moonsize] arc [start angle=90,end angle=270,y radius=\moonsize,x radius={\moonsize - #3*2*\moonsize}];}\tmp
    \fi
    \end{scope}
    \edef\tmp{\noexpand\draw (axis cs:#1,#2) node [font=\noexpand\scriptsize,below=0.7\moonsize] {\noexpand\pgfmathparse{int(round(#3*1000))/10}\noexpand\pgfmathprintnumber{\noexpand\pgfmathresult}\%};}\tmp
}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
xlabel={Time (hr)},
ylabel={Altitude ($^\circ$)},
xmin=0,
xmax=12,
ymin=-90,
ymax=90,
xtick={0,1,...,12},
ytick={-80,-60,...,80}
]

\pgfplotstableread{Tracking.txt}\Tracking;

\pgfplotsinvokeforeach {1,2,...,6} {
    \pgfplotstablegetelem{#1}{m}\of{\Tracking}\edef\MoonFigurePointX{\pgfplotsretval}
    \pgfplotstablegetelem{#1}{h_Moon}\of{\Tracking}\edef\MoonFigurePointY{\pgfplotsretval}
    \pgfplotstablegetelem{#1}{k_Moon}\of{\Tracking}\edef\MoonFigureFraction{\pgfplotsretval}
    \pgfplotstablegetelem{#1}{i_Moon}\of{\Tracking}\edef\MoonFigurePhase{\pgfplotsretval}
    \pgfplotstablegetelem{#1}{chi_Moon}\of{\Tracking}\edef\MoonFigureAngle{\pgfplotsretval}
    \drawmoon{\MoonFigurePointX}{\MoonFigurePointY}{\MoonFigureFraction}{\MoonFigurePhase}{\MoonFigureAngle}
}

\end{axis}
\end{tikzpicture}
\end{document}

接受的答案这一页这一页非常有帮助。

相关内容