# Plot one function per row of table

I want to plot a polynomial that is parametrized by an additional parameter d. I took samples of the domain of d and stored the coefficients of the polynomial for each of these samples in a table:

d       a0       a1        a2         a3        a4
0       0.31632  0.038794  -0.637117  0.457322  -0.0940009
0.002   0.316319 0.0387949 -0.637115  0.457321  -0.0940008
0.4     0.130744 0.0171396 -0.292042  0.2209    -0.0479512
...


Now I would like to plot up to 100 of these polynomials into the same plot. Is there a way that does not require me to hand code each polynomial to plot or to sample each polynomial in an external tool? (Doing so from within the Latex tool chain would be fine.)

To summarize it: In my case, the rows of the table don't represent coordinates to plot but coefficients of polynomials that I want to plot. Therefore, I don't see how to use pgfplot's \addplot table to get the output that I want.

The effect of the code should be like

\documentclass{standalone}
\usepackage{pgfplots, pgfplotstable}
\pgfplotsset{compat=1.12}
\begin{document}

\begin{tikzpicture}
\begin{axis}[domain=0:2]
\addplot[mark=none] {0.31632  + x*(0.038794  + x*(-0.637117 + x*(0.457322 + x*-0.0940009)))};
\addplot[mark=none] {0.311765 + x*(0.0408345 + x*(-0.633668 + x*(0.454718 + x*-0.0935363)))};
\addplot[mark=none] {0.130744 + x*(0.0171396 + x*(-0.292042 + x*(0.2209   + x*-0.0479512)))};
\end{axis}
\end{tikzpicture}
\end{document}


but without the manual repetition.

The result would look like:

-

## 2 Answers

Here's a way that uses a pgfplotsinvokeforeach approach.

There are a few important parts, including:

% declare a polynomial function
\pgfmathdeclarefunction{mypoly}{6}{%
% #1: a0
% #2: a1
% #3: a2
% #4: a3
% #5: a4
% #6: x
\pgfmathparse{#1+#2*#6%
+#3*#6^2%
+#4*#6^3%
+#5*#6^4}%
}


which, as you can see, defines your polynomial.

You'll see that this is invoked in the addplot command as

 \addplot[domain=0:2,red,thick]{mypoly(\aZero,\aOne,\aTwo,\aThree,\aFour,x)};


Here's the complete code:

% arara: pdflatex
% !arara: indent: {overwrite: yes}
\documentclass[tikz]{standalone}
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.12}

% read in the coefficients
\pgfplotstableread[col sep=space]{
d       a0       a1        a2         a3        a4
0       0.31632  0.038794  -0.637117  0.457322  -0.0940009
1      0.311765 0.0408345 -0.633668  0.454718  -0.0935363
2       0.130744 0.0171396 -0.292042  0.2209    -0.0479512
}\coefficients

% count number of rows
\pgfplotstablegetrowsof\coefficients
\pgfmathsetmacro\numberofrows{\pgfplotsretval-1}

% declare a polynomial function
\pgfmathdeclarefunction{mypoly}{6}{%
% #1: a0
% #2: a1
% #3: a2
% #4: a3
% #5: a4
% #6: x
\pgfmathparse{#1+#2*#6%
+#3*#6^2%
+#4*#6^3%
+#5*#6^4}%
}

\begin{document}

\begin{tikzpicture}
\begin{axis}[domain=0:2]
% loop through the rows of the table
\pgfplotsinvokeforeach{0,...,\numberofrows}{
% define each of a0, a1, a2, a3, a4
% a0
\pgfplotstablegetelem{#1}{[index]1}\of\coefficients
\pgfmathsetmacro{\aZero}{\pgfplotsretval}
% a1
\pgfplotstablegetelem{#1}{[index]2}\of\coefficients
\pgfmathsetmacro{\aOne}{\pgfplotsretval}
% a2
\pgfplotstablegetelem{#1}{[index]3}\of\coefficients
\pgfmathsetmacro{\aTwo}{\pgfplotsretval}
% a3
\pgfplotstablegetelem{#1}{[index]4}\of\coefficients
\pgfmathsetmacro{\aThree}{\pgfplotsretval}
% a4
\pgfplotstablegetelem{#1}{[index]5}\of\coefficients
\pgfmathsetmacro{\aFour}{\pgfplotsretval}
% add the polynomial plot
\addplot[domain=0:2,red,thick]{mypoly(\aZero,\aOne,\aTwo,\aThree,\aFour,x)};
}
\end{axis}
\end{tikzpicture}
\end{document}

-
this code could probably be reduced by defining the coefficients using a loop... perhaps some \roman magic. don't have time at the moment, may return to it, but it works as is :) – cmhughes Feb 22 at 14:38

I would probably just use a scripting language and create the LaTeX source code. Here is an example in Python.

#!/usr/bin/env python
import csv
with open('data.csv', 'rb') as csvfile:
coeff = csv.reader(csvfile, delimiter=',')
coeff.next()
for row in coeff:
print("\\addplot[mark=none] {" + row[1] +
" + x * (" + row[2] +
" + x * (" + row[3] +
" + x * (" + row[4] +
" + x * " + row[5] + ")))};")


To make it easier to load the coefficients I converted your data into a proper csv file.

d,a0,a1,a2,a3,a4
0,0.31632,0.038794,-0.637117,0.457322,-0.0940009
0.002,0.316319,0.0387949,-0.637115,0.457321,-0.0940008


If you redirect the output to a file like this

python createPlots.py > plots.tex


you can then load it later within your main tex file using \input{}.

\documentclass{standalone}
\usepackage{pgfplots, pgfplotstable}
\pgfplotsset{compat=1.12}
\begin{document}

\begin{tikzpicture}
\begin{axis}[domain=0:2]
\input{plots.tex}
\end{axis}
\end{tikzpicture}
\end{document}


EDIT:

You can of course also run your script from within LaTeX (needs --shell-escape).

\documentclass{standalone}
\usepackage{pgfplots, pgfplotstable}
\pgfplotsset{compat=1.12}
\begin{document}

\begin{tikzpicture}
\begin{axis}[domain=0:2]
\immediate\write18{python createPlots.py > plots.tex}
\input{plots.tex}
\end{axis}
\end{tikzpicture}
\end{document}


EDIT 2:

So here is a LuaTeX solution. It expects also the properly formatted csv file.

\documentclass{standalone}
\usepackage{pgfplots, pgfplotstable}
\pgfplotsset{compat=1.12}
\usepackage{luacode}
\begin{document}

\begin{tikzpicture}
\begin{axis}[domain=0:2]
\begin{luacode}
firstLineSkipped = false
for line in io.lines("data.csv") do
if firstLineSkipped then
tex.print("\\addplot[mark=none] {" .. line:gsub('.-,','', 1):gsub(",", "  + x*(", 4) .. ")))};");
else
firstLineSkipped = true
end
end
\end{luacode}
\end{axis}
\end{tikzpicture}
\end{document}

-
That is basically what I wanted to avoid, an extra step outside of the tool chain. – Nobody Feb 22 at 16:13
@Nobody See my edit. – Benjamin Feb 22 at 16:27
Okay that avoids calling the tool by hand. I still prefer cmhughes' answer because it does not have an external dependency (like python). – Nobody Feb 22 at 19:28
Why use python when you have LuaTeX? – Martin Schröder Feb 22 at 23:46
@Nobody: Your question does not seem to be specific to luatex. – Martin Schröder Feb 23 at 19:25