Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

Using some plain old Metapost code I am able to create a basic plot of linear regression. The question is: Can I create a graphics with e.g. TikZ which allows me to specify a few points coordinates (black) )and two points (or the coefficients of the linear model) for the regression line and then automatically

  • draws the red lines
  • plots the green points
  • shows a calculated sum of squares in the diagram

It could come handy to do it in LaTeX directly to show how the parameters of the regression line influence the sum of squared differences.

enter image description here

share|improve this question
    
You need to make some calculations outside TeX (Tikz) –  Alain Matthes Feb 9 '13 at 6:41
1  
@Alain: The algorithm for linear regression is quite simple; I'm sure the pgf math engine (or the fp package) can handle it. –  Hendrik Vogt Feb 9 '13 at 7:36
    
simple ... yes but it depends on the required accuracy and values ​​that must be studied. It is indeed possible to use FP but I think that the code by using a calculator to find the regression line is more simpler. It will be fine to know some requests (values, accuracy) –  Alain Matthes Feb 9 '13 at 8:01
    
The values are either integer or have one digit after the comma. I wouldn't go so far as to calculate the regression line, it would be sufficient to show the sum of squares for a given line. I want to visualize how the sum of squares changes if you edit the parameters of the model... –  Uwe Ziegenhagen Feb 9 '13 at 8:42
add comment

2 Answers

up vote 5 down vote accepted

Here's a solution based on the datatool package:

\documentclass{article}
\usepackage{datatool}
\usepackage{dataplot}

\begin{document}

% define data set (could also be read from csv file)
\DTLnewdb{mydata}
\DTLnewrow{mydata}%
\DTLnewdbentry{mydata}{x}{1}%
\DTLnewdbentry{mydata}{y}{2.3}%
\DTLnewrow{mydata}%
\DTLnewdbentry{mydata}{x}{2}%
\DTLnewdbentry{mydata}{y}{3.4}%
\DTLnewrow{mydata}%
\DTLnewdbentry{mydata}{x}{3}%
\DTLnewdbentry{mydata}{y}{4.1}%


% calculate extra columns 
\DTLforeach{mydata}{%
  \valx=x,%
  \valy=y}{%
  \DTLmul{\result}{\valx}{\valx}%
  \DTLappendtorow{xx}{\result}%
  \DTLmul{\result}{\valx}{\valy}%
  \DTLappendtorow{xy}{\result}%
}

% calculate required averages                 
\DTLmeanforcolumn{mydata}{x}{\mx}
\DTLmeanforcolumn{mydata}{y}{\my}
\DTLmeanforcolumn{mydata}{xx}{\mxx}
\DTLmeanforcolumn{mydata}{xy}{\mxy}
\DTLvarianceforcolumn{mydata}{x}{\vx}

% calculate slope
\DTLmul{\tmpa}{\mx}{\my}
\DTLsub{\tmpb}{\mxy}{\tmpa}
\DTLdiv{\fita}{\tmpb}{\vx}
\DTLround{\fitar}{\fita}{3}

% calculate intercept
\DTLmul{\tmpa}{\mxx}{\my}
\DTLmul{\tmpb}{\mxy}{\mx}
\DTLsub{\tmpc}{\tmpa}{\tmpb}
\DTLdiv{\fitb}{\tmpc}{\vx}
\DTLround{\fitbr}{\fitb}{3}


% prepare data for line
\DTLminforcolumn{mydata}{x}{\minx}
\DTLmaxforcolumn{mydata}{x}{\maxx}
\DTLmul{\tmpa}{\minx}{\fita}
\DTLadd{\tmpb}{\tmpa}{\fitb}
\DTLmul{\tmpa}{\maxx}{\fita}
\DTLadd{\tmpc}{\tmpa}{\fitb}


\renewcommand*{\DTLplotatendtikz}{%
  \draw (\minx,\tmpb) -- (\maxx,\tmpc);
}

\begin{figure}[htbp]
\centering
\DTLplot{mydata}{x=x,y=y,width=3in,height=3in}
\caption{The fit function is $\fitar\ x + \fitbr$}
\end{figure}

\end{document}
share|improve this answer
add comment

This is not a complete answer, as I couldn't make the connection lines drawn in a clean way.

I was thinking of using error bars depending on the sign of the error but the direction switch is not suitable for that. I'll come back to this again probably with a foreach or something similar. Please let me know if you have a better idea.

You can do pretty much every other thing with pgfplots. Here is the table for the regression entries and the accumulated sums of squares.

\documentclass{article}
\usepackage{pgfplots,pgfplotstable}
\pgfplotsset{compat=1.7}
\pgfplotstableread{%Input some data
x y
0.2 0.3
0.4 0.7
0.6 0.4
0.8 1.2
1.0 0.6
1.2 0.5
1.4 0.8
1.6 0.1
1.8 0.7
2.0 0.1 
}\mytable

% create the `regression' column:
\pgfplotstablecreatecol[linear regression]{reg}{\mytable}
% create the sos column
\pgfplotstablecreatecol[
create col/assign/.code={%
\ifx\pgfmathaccuma\pgfutil@empty
  \let\pgfmathaccuma=0
\fi
\getthisrow{y}\yentry
\getthisrow{reg}\rentry
    \pgfmathparse{\pgfmathaccuma + (abs(\yentry-\rentry))^2}
        \let\pgfmathaccuma=\pgfmathresult
    \pgfkeyslet{/pgfplots/table/create col/next content}\pgfmathresult
}
]{sos}{\mytable}

\begin{document}

%Typeset the table
\pgfplotstabletypeset{\mytable}
%
\hspace{1cm}
% Draw the graph
\begin{tikzpicture}[baseline=(current bounding box.center)]
\begin{axis}[
axis y line=left,
axis x line=bottom,
xmin=0,xmax=1.2,
ymin=0]
\addplot[only marks,mark size=1pt] table {\mytable};
\addplot[mark=*,mark size=1pt,mark options={green},draw=blue,] table[x=x,y=reg] {\mytable};

\end{axis}
\end{tikzpicture}

\end{document}

enter image description here

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.