我有一个 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}