# Linear Regression with symbolic x-coordinates

I have been having difficulty with this problem for a few days now so I'm hoping you can come to my aid.

I am trying to create a line of linear regression for a very small chart using pgfplots. Unfortunately my x-axis has symbolic x-coordinates and the compiler does not seem to like that at all for linear regression.

The plot works fine without the linear regression line but as soon as I add it everything goes to hell in a hand basket.

 83 \begin{figure}[h]
84         \centering
85         \begin{tikzpicture}
86                 \begin{axis}[
87                         title=Wavelength vs. Stopping Voltage,
88                         xlabel={Wavelength},
89                         ylabel={Stopping Voltage (Volts)},
90                         symbolic x coords={Yellow, Green, Blue, Violet, U.V.}
91                         ]
92
95                                 symbolic x coords={Yellow, Green, Blue, Violet, U.V.},
96                                 y={create col/linear regression={y=Voltage}}] {lab3.data};
97
98                 \end{axis}
99         \end{tikzpicture}
100 \end{figure}

• Welcome to TeX.sx! Please add a minimal working example (MWE) that illustrates your problem. It will be much easier for us to reproduce your situation and find out what the issue is when we see compilable code, starting with \documentclass{..} and ending with \end{document}. And please remove the line number from the code (otherwise somebody who wants to help you has to do it). Commented Nov 21, 2014 at 22:02

Since you did not provide an MWE, I'm making a guess about the format of your .data file:

Yellow  0
Green   1
Blue    2
Violet  3
U.V.    3


I create this using the filecontents package at the top of my example code. I used the filename lab3-paul.data so that it doesn't overwrite your real data file. :-)

The main issue here is that pgfplots needs some sort of numerical value for the x-coordinate in order to perform the calculations for a linear regression. If modifying your data file is an option, you could add a numerical x-value column (could be light wavelength in nanometer for your case, for instance, but it really doesn't matter). If this is an option, use the symbolic x-coordinate for plotting and the numerical x-coordinate for the regression.

For the remainder of this answer, I assume that modifying the data file is not an option. We can create a dummy column with some numerical value to use during the regression, but we have to fall back to the more sophisticated tools available directly at the pgfplotstable level. (pgfplots has an interface to only a limited set of capabilities via \addplot table {...}.)

The first step is to load the data, with

\pgfplotstableread{lab3-paul.data}\loadedtable


Now we can refer to our table as \loadedtable (this name is arbitrary) from this point forward.

Next, set up the created column:

\pgfplotstableset{create on use/xnum/.style={create col/expr={\pgfplotstablerow}}}


This will create a column called xnum (again, arbitrary name) that will be created on use (that is, whenever queried in a pgfplots/pgfplotstable command). The column's value is simply the current row index.

For the first plot (of the original data), nothing needs to change, but since we've already loaded the data into \loadedtable, we might as well use that instead of loading it again from the file:

\addplot table {\loadedtable};


Then, for the regression line, we only need to specify that we want to use our calculated column xnum for the x-value for the regression calculations:

\addplot table [y={create col/linear regression={x=xnum}}] {\loadedtable};


In the complete code below, I've also added some legend entries for clarity:

\RequirePackage{filecontents}
\begin{filecontents*}{lab3-paul.data}
Yellow  0
Green   1
Blue    2
Violet  3
U.V.    3
\end{filecontents*}

\documentclass{standalone}
\usepackage{pgfplots,pgfplotstable}
\pgfplotsset{compat=1.11}
\pgfplotstableset{create on use/xnum/.style={create col/expr={\pgfplotstablerow}}}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
legend pos=south east,
title=Wavelength vs. Stopping Voltage,
xlabel={Wavelength},
ylabel={Stopping Voltage (Volts)},
symbolic x coords={Yellow, Green, Blue, Violet, U.V.}
]