# How can I fit the original data with exponential or polynomial functions via pgfplots?

I am trying to plot the following data with a curve fitting via pgfplots.

It seems linear regression is not suitable for my case. So I would prefer to have exponential or polynomial curve fitting on these data. How can I implement it?

Below is the current code:

% arara: pdflatex: { shell: yes }

\documentclass[border=1mm, png]{standalone}
\usepackage{siunitx}
\usepackage{pgfplots}
\pgfplotsset{compat=1.10}
\usepackage{pgfplotstable}
\usepackage{filecontents}
\begin{filecontents*}{myData.dat}
X     Y
2   275.68
3   1175.26
4   1351.60
5   1485.57
6   1583.30
7   1861.28
8   2095.39
9   2574.54
10  2841.74
11  2914.16
12  3965.12
13  3787.68
14  5294.83
21  10504.49
\end{filecontents*}

\begin{document}
\begin{tikzpicture}
\pgfplotsset{%
,width=10cm
,legend style={font=\footnotesize}
}
\begin{axis}[%
,xlabel=Numbers $N$ in \si{\gram\per\liter}
,ylabel=Ratio
,ymin=0
,xmin=0
,scaled y ticks=base 10:0
,legend cell align = left
,legend pos = north west
]
\addplot+[no markers,red] table [y={create col/linear regression={y=Y}}]{myData.dat};
Linear trend $(y=\pgfmathprintnumber{\pgfplotstableregressiona} \cdot x \pgfmathprintnumber[print sign]{\pgfplotstableregressionb})$} %
\end{axis}
\end{tikzpicture}
\end{document}


Which yields:

-
Did you take a look on how to use gnuplot in pgfplots? I guess, this kind of calculation needs some higher tool. Personally, I would recommend to calculate the curve you need via sageTeX and to plot it afterwards. –  LaRiFaRi Jun 26 at 11:41
Well, Excel is a powerful calculation tool... (not that I like it ;-) ). If there is something implemented here, you should be able to find it by the words "fitting", "regression", "approximation", "polynomial" or "Taylor" in the manuals of pgfplots and pgfplotstable. Please have a look! I didn't check. –  LaRiFaRi Jun 26 at 11:57
Off topic: 1. $-$ is a minus sign. Therefore I would not set the unit of your ratio in math-mode. (As units should not be set in square brackets (ISO & SI) and a "ratio" has the unit 1 by definition, I would leave it away completely.). 2. please make you code minimal. You just need siunitx, pgfplots, and pgfplotstable for this example. –  LaRiFaRi Jun 26 at 12:04
@LCFactorization: You can do this from within PGFPlots by using gnuplot in the background. See Non-linear curve fitting with gnuplot (this may be a duplicate of that question). –  Jake Jun 26 at 12:35
@LCFactorization: PGFPlots can only do linear regression. The question "how can I linearize a polynomial / exponential equation?" seems more appropriate for math.stackexchange.com. –  Jake Jun 26 at 12:43

This is an attempt via polynomial fit and the use of gnuplot. Therefore this requires one to compile the code with shell-escape enabled, and gnuplot has to be installed on your system.

Edit: The OP finds how to find the actually parameters after curve fitting. The answer is here: show fitted values which needs two lines of code

set print "parameters.dat"; % Open a file to save the parameters into
print a, b;                 % Write the parameters to file


Code

\documentclass[border=10pt]{standalone}
\usepackage{pgf,tikz}
\usepackage{siunitx}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\usepackage{filecontents}
\usepackage{graphicx}
\usepackage{latexsym}
\usepackage{keyval}
\usepackage{ifthen}
\usepackage{moreverb}
\usepackage{gnuplottex}%[miktex]%[shell]
\usepackage{pgfplotstable}
\pgfplotsset{compat=1.5}

\usepackage{filecontents}
\begin{document}

\begin{filecontents}{data.csv}
X     Y
2   275.68
3   1175.26
4   1351.60
5   1485.57
6   1583.30
7   1861.28
8   2095.39
9   2574.54
10  2841.74
11  2914.16
12  3965.12
13  3787.68
14  5294.83
21  10504.49
};
\end{filecontents}

\begin{tikzpicture}
\pgfplotsset{width=10cm,
legend style={font=\footnotesize}}
\begin{axis}[
xlabel={Numbers [N,\si{\gram\per\liter}]},
ylabel={Ratio $[-]$},
ymin =0,
ytick = {200,2000,4000,6000,8000,10000},
y tick label style={
/pgf/number format/.cd,
fixed,
fixed zerofill,
precision=0,
/tikz/.cd
},
yticklabel=\pgfmathprintnumber{\tick},
scaled y ticks=base 10:0,
legend cell align = left,
legend pos = north west]
\addlegendentry{Ratio of {\em tfml} to {\em gGN}}
% linear curve fitting
y={create col/linear regression={y=Y}}] % compute a linear regression from the input table
{data.csv};
linear trend $\left(y=\pgfmathprintnumber{\pgfplotstableregressiona} \cdot x \pgfmathprintnumber[print sign]{\pgfplotstableregressionb}\right)$} %
% polynomial fit
\addplot [no markers, blue] gnuplot [raw gnuplot] { % allows arbitrary gnuplot commands
f(x) = a*x**2+b*x;     % Define the function to fit
a=260;b=-270;          % Set reasonable starting values here
fit f(x) 'data.csv' u 1:2 via a,b; % Select the file, starts at col 1 and two variables
plot [x=2:21] f(x);    % Specify the range to plot
set print "parameters.dat";  % Open a file to save the parameters
print a, b;                  % Write the parameters to file
};
\pgfplotstablegetelem{0}{0}\of\parameters \pgfmathsetmacro\paramA{\pgfplotsretval} % Get first element, save into \paramA
\pgfplotstablegetelem{0}{1}\of\parameters \pgfmathsetmacro\paramB{\pgfplotsretval}
polynomial fit: $y=\pgfmathprintnumber{\paramA} x^2 \pgfmathprintnumber[print sign]{\paramB} x$
}
\end{axis}
\end{tikzpicture}
\end{document}

-
thank you. Is it possible to explicitly show the fitted values of a and b in the legendentry? –  LCFactorization Jun 26 at 12:51
The answer is probably here: tex.stackexchange.com/questions/29633/… thanks –  LCFactorization Jun 26 at 13:10
Yes, you got it. I was searching the auxiliary file, to see if any info was left in *.plot.gnuplot and *.plot.table file, but none. Then your finding prompt me to try. Yes, you find the answer. –  Jesse Jun 26 at 13:19