TikZ:带残差的回归线

TikZ:带残差的回归线

期望输出

R我使用制作了此图ggplot2在此处输入图片描述现在我想使用 重现此图Tikz。我的 MWE 是:

\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}

\begin{document}

\pgfmathsetseed{1138} % set the random seed
\pgfplotstableset{ % Define the equations for x and y
    create on use/x/.style={create col/expr={42+2*\pgfplotstablerow}},
    create on use/y/.style={create col/expr={(0.6*\thisrow{x}+130)+5*rand}}
}
% create a new table with 30 rows and columns x and y:
\pgfplotstablenew[columns={x,y}]{30}\loadedtable



\begin{tikzpicture}
\begin{axis}[
xlabel=Weight (kg), % label x axis
ylabel=Height (cm), % label y axis
axis lines=left, %set the position of the axes
xmin=40, xmax=105, % set the min and max values of the x-axis
ymin=150, ymax=200, % set the min and max values of the y-axis
clip=false
]

\addplot [only marks] table {\loadedtable};
\addplot [no markers, thick, black] table [y={create col/linear regression={y=y}}] {\loadedtable} ;
\end{axis}

\end{tikzpicture}
\end{document}

在此处输入图片描述

任何帮助和提示都将不胜感激。谢谢

答案1

如果您明确创建一个regression包含回归线值的新列(而不是使用样式create on demand),则可以使用以下样式以不同的颜色绘制残差:

\pgfplotsset{
    colored residuals/.style 2 args={
        only marks,
        scatter,
        point meta=explicit,
        colormap={redblue}{color=(#1) color=(#2)},
        error bars/y dir=minus,
        error bars/y explicit,
        error bars/draw error bar/.code 2 args={
            \pgfkeys{/pgf/fpu=true}
            \pgfmathtruncatemacro\positiveresidual{\pgfplotspointmeta<0}
            \pgfkeys{/pgf/fpu=false}
            \ifnum\positiveresidual=0
                \draw [#2] ##1 -- ##2;
            \else
                \draw [#1] ##1 -- ##2;
            \fi
        },
        /pgfplots/table/.cd,
            meta expr=(\thisrow{y}-\thisrow{regression})/abs(\thisrow{y}-\thisrow{regression}),
            y error expr=\thisrow{y}-\thisrow{regression}
    },
    colored residuals/.default={red}{blue}
}

colored residuals={cyan}{orange}您可以使用可选参数(例如)更改用于负残差和正残差的颜色。

在此处输入图片描述


\documentclass[tikz, border=5pt]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}

\begin{document}

\pgfmathsetseed{1138} % set the random seed
\pgfplotstableset{ % Define the equations for x and y
    create on use/x/.style={create col/expr={42+2*\pgfplotstablerow}},
    create on use/y/.style={create col/expr={(0.6*\thisrow{x}+130)+5*rand}}
}
% create a new table with 30 rows and columns x and y:
\pgfplotstablenew[columns={x,y}]{30}\loadedtable

% Calculate the regression line
\pgfplotstablecreatecol[linear regression]{regression}{\loadedtable}

\pgfplotsset{
    colored residuals/.style 2 args={
        only marks,
        scatter,
        point meta=explicit,
        colormap={redblue}{color=(#1) color=(#2)},
        error bars/y dir=minus,
        error bars/y explicit,
        error bars/draw error bar/.code 2 args={
            \pgfkeys{/pgf/fpu=true}
            \pgfmathtruncatemacro\positiveresidual{\pgfplotspointmeta<0}
            \pgfkeys{/pgf/fpu=false}
            \ifnum\positiveresidual=0
                \draw [#2] ##1 -- ##2;
            \else
                \draw [#1] ##1 -- ##2;
            \fi
        },
        /pgfplots/table/.cd,
            meta expr=(\thisrow{y}-\thisrow{regression})/abs(\thisrow{y}-\thisrow{regression}),
            y error expr=\thisrow{y}-\thisrow{regression}
    },
    colored residuals/.default={red}{blue}
}

\begin{tikzpicture}
\begin{axis}[
xlabel=Weight (kg), % label x axis
ylabel=Height (cm), % label y axis
axis lines=left, %set the position of the axes
xmin=40, xmax=105, % set the min and max values of the x-axis
ymin=150, ymax=200, % set the min and max values of the y-axis
]

\makeatletter
\addplot [colored residuals] table {\loadedtable};
\addplot [
    no markers,
    thick, black
] table [y=regression] {\loadedtable} ;
\end{axis}

\end{tikzpicture}
\end{document}

答案2

它有点冗长,但它做了它该做的事情。我在里面用一些注释来解释代码。

编辑 @Jake 方法更优雅,但我也得到了相同的结果,所以我在代码中添加了更改。

\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.9}

\begin{document}

\pgfmathsetseed{1138} % set the random seed
\pgfplotstableset{ % Define the equations for x and y
    create on use/x/.style={create col/expr={42+2*\pgfplotstablerow}},
    create on use/y/.style={create col/expr={(0.6*\thisrow{x}+130)+5*rand}}
}

% create a new table with 30 rows and columns x and y:
\pgfplotstablenew[columns={x,y}]{30}\loadedtable

% Determine no. of rows
\pgfplotstablegetrowsof{\loadedtable} 
\pgfmathsetmacro{\rows}{\pgfplotsretval}
\pgfmathsetmacro{\r}{\rows-1}

\begin{tikzpicture}
\begin{axis}[
    xlabel=Weight (kg), % label x axis
    ylabel=Height (cm), % label y axis
    axis lines=left, %set the position of the axes
    xmin=40, xmax=105, % set the min and max values of the x-axis
    ymin=150, ymax=200, % set the min and max values of the y-axis
    clip=false]

    \addplot [only marks] table {\loadedtable};
    \addplot [no markers, thick, black] table [y={create col/linear regression={y=y}}] {\loadedtable};

    % Save the coefficients of the linear regression
    \pgfmathsetmacro{\rega}{\pgfplotstableregressiona}
    \pgfmathsetmacro{\regb}{\pgfplotstableregressionb}

    % loop on the number of rows
    \foreach \i in {0,1,...,\r}{
        % get element x and y of the table
        \pgfplotstablegetelem{\i}{x}\of\loadedtable
        \pgfmathsetmacro{\x}{\pgfplotsretval}
        \pgfplotstablegetelem{\i}{y}\of\loadedtable
        \pgfmathsetmacro{\y}{\pgfplotsretval}
        \pgfmathsetmacro{\reg}{\rega*\x+\regb}
        \pgfmathsetmacro{\dif}{\reg-\y}
        % draw line between points and the linear regression
        % the \edef\temp{\noexpand ... } is for using macro inside \foreach
        \ifdim \dif px > 0px\relax
        \edef\temp{\noexpand\draw[blue, thick] (axis cs:\x,\y)--(axis cs:\x,\reg);}
        \edef\tempp{\noexpand\addplot[mark=*,blue] coordinates {(\x,\y)};}
        \else
        \edef\temp{\noexpand\draw[red, thick] (axis cs:\x,\y)--(axis cs:\x,\reg);}
        \edef\tempp{\noexpand\addplot[mark=*,red] coordinates {(\x,\y)};}
        \fi
        \temp
        \tempp
    }

\end{axis}

\end{tikzpicture}
\end{document}

在此处输入图片描述

相关内容