PGF 变量内容被覆盖

PGF 变量内容被覆盖

我有一个 pgfplots 图,我在其中绘制了许多曲线并对它们进行线性回归以获得斜率。我最初编写的 LaTeX 代码包含重复多次的同一组线条,只改变了图的颜色和要处理的数据的名称。因此,我尝试创建所有这些行的宏分组以简化代码(如果我想更改某些内容,也可以方便工作!)

\documentclass[margin=1cm]{standalone}
\usepackage{pgfplots, pgfplotstable}
\pgfplotsset{compat=newest}

\begin{filecontents*}[overwrite]{data1.csv}
x y
0 0
1 2
2 4
3 6
4 7
\end{filecontents*}
\begin{filecontents*}[overwrite]{data2.csv}
x y
0 0
1 1
2 4
3 9
4 13
\end{filecontents*}

\pgfplotstableread{data1.csv}\dataOne
\pgfplotstableread{data2.csv}\dataTwo

\newcommand{\plotAndComputeLinreg}[2]{
    \addplot+[#1, mark=none, dashed] table[x=x, y={create col/linear regression={y=y}}]{#2};
    \xdef\slope{\pgfplotstableregressiona}
    \addlegendentry{Slope : \pgfmathprintnumber{\slope}}
    \addplot+[#1, only marks, forget plot, mark=+, solid] table[x=x, y=y] {#2};
}

\begin{document}
    \begin{tikzpicture}
    \begin{axis}
        \plotAndComputeLinreg{red}{\dataOne}
        \plotAndComputeLinreg{blue}{\dataTwo}
    \end{axis}
    \end{tikzpicture}
\end{document}

这是我所做的 ECM,结果如下:

在此处输入图片描述

如您所见,两条曲线显示的斜率相同!红色曲线的斜率应为1.8

我认为这是因为 pgf 为变量设置了一个新值\slope,最后它显示了内存中的值。有没有办法避免这种情况?

======================================

编辑 :@egreg 对我最初的帖子的回答如下。然而,我面临的情况比我给出的 ECM 更复杂,而且我没能适应它。

在我想要使用的宏中,我绘制了 2 条曲线并计算了 2 个线性回归,但我想在单个图例条目中显示 2 个斜率:

\documentclass[margin=1cm]{standalone}
\usepackage{pgfplots, pgfplotstable}
\pgfplotsset{compat=newest}

\begin{filecontents*}[overwrite]{\jobname-data1.csv}
x error_l2 error_h1
0 0 1
1 2 2
2 4 3
3 6 4
4 7 5
\end{filecontents*}
\begin{filecontents*}[overwrite]{\jobname-data2.csv}
x error_l2 error_h1
0 0 1
1 1 2
2 4 8
3 9 11
4 13 15
\end{filecontents*}
\pgfplotstableread{\jobname-data1.csv}\dataOne
\pgfplotstableread{\jobname-data2.csv}\dataTwo

\newcommand{\plotAndComputeLinreg}[2]{
    \addplot+[#1, mark=none, dashed, forget plot] table[x=x, y={create col/linear regression={y=error_l2}}]{#2};
    \xdef\slopeL{\pgfplotstableregressiona}
    \addplot+[#1, mark=none, solid] table[x=x, y={create col/linear regression={y=error_h1}}]{#2};
    \xdef\slopaH{\pgfplotstableregressiona}
    \addlegendentry{Slopes : L2 \pgfmathprintnumber{\slopeL}, H1 \pgfmathprintnumber{\slopaH}}
    \addplot+[#1, only marks, forget plot, mark=+] table[x=x, y=error_l2] {#2};
    \addplot+[#1, only marks, forget plot, mark=+] table[x=x, y=error_h1] {#2};
}

\begin{document}
    \begin{tikzpicture}
    \begin{axis}
        \plotAndComputeLinreg{red}{\dataOne}
        \plotAndComputeLinreg{blue}{\dataTwo}
    \end{axis}
    \end{tikzpicture}
\end{document}

答案1

您需要\slope在呼叫时进行扩展\addlegendentry,否则最后的含义将在打印时被拾取。

但没有必要\slope\pgfplotstableregressiona以前那样经过。

\begin{filecontents*}{\jobname-data1.csv}
x y
0 0
1 2
2 4
3 6
4 7
\end{filecontents*}
\begin{filecontents*}{\jobname-data2.csv}
x y
0 0
1 1
2 4
3 9
4 13
\end{filecontents*}

\documentclass[margin=1cm]{standalone}
\usepackage{pgfplots, pgfplotstable}
\pgfplotsset{compat=newest}

\pgfplotstableread{\jobname-data1.csv}\dataOne
\pgfplotstableread{\jobname-data2.csv}\dataTwo

\newcommand{\printslope}{%
  \expandafter\doprintslope\expandafter{\pgfplotstableregressiona}
}
\newcommand{\doprintslope}[1]{\addlegendentry{Slope: \pgfmathprintnumber{#1}}}

\newcommand{\plotAndComputeLinreg}[2]{
    \addplot+[#1, mark=none, dashed] table[x=x, y={create col/linear regression={y=y}}]{#2};
    \printslope
    \addplot+[#1, only marks, forget plot, mark=+, solid] table[x=x, y=y] {#2};
}

\begin{document}
    \begin{tikzpicture}
    \begin{axis}
        \plotAndComputeLinreg{red}{\dataOne}
        \plotAndComputeLinreg{blue}{\dataTwo}
    \end{axis}
    \end{tikzpicture}
\end{document}

在此处输入图片描述

对于更复杂的任务,我建议使用\expanded

\begin{filecontents*}[overwrite]{\jobname-data1.csv}
x error_l2 error_h1
0 0 1
1 2 2
2 4 3
3 6 4
4 7 5
\end{filecontents*}
\begin{filecontents*}[overwrite]{\jobname-data2.csv}
x error_l2 error_h1
0 0 1
1 1 2
2 4 8
3 9 11
4 13 15
\end{filecontents*}

\documentclass[margin=1cm]{standalone}
\usepackage{pgfplots, pgfplotstable}
\pgfplotsset{
  compat=newest,
  legend cell align=left,
}

\pgfplotstableread{\jobname-data1.csv}\dataOne
\pgfplotstableread{\jobname-data2.csv}\dataTwo

\newcommand{\plotAndComputeLinreg}[2]{%
  \addplot+[
    #1,
    mark=none,
    dashed,
    forget plot
  ] table[x=x, y={create col/linear regression={y=error_l2}}]{#2};
  \edef\slopeL{\pgfplotstableregressiona}
  \addplot+[
    #1,
    mark=none,
    solid
  ] table[x=x, y={create col/linear regression={y=error_h1}}]{#2};
  \edef\slopaH{\pgfplotstableregressiona}
  \expanded{%
    \noexpand\addlegendentry{%
      Slopes: L2 \noexpand\pgfmathprintnumber{\slopeL},
              H1 \noexpand\pgfmathprintnumber{\slopaH}\hfill
    }%
  }
  \addplot+[#1, only marks, forget plot, mark=+] table[x=x, y=error_l2] {#2};
  \addplot+[#1, only marks, forget plot, mark=+] table[x=x, y=error_h1] {#2};
}

\begin{document}

\begin{tikzpicture}
  \begin{axis}
    \plotAndComputeLinreg{red}{\dataOne}
    \plotAndComputeLinreg{blue}{\dataTwo}
  \end{axis}
\end{tikzpicture}

\end{document}

在此处输入图片描述

相关内容