3

I’m having trouble getting pgfplots to typeset very small numbers, e.g. 6.82e-08. I don’t know if the problem lies in it being a very small number, or if it’s because of the interaction with reading variable data generated from gnuplot.

The example below will generate two plots. The first is generated from “external” data, and has gnuplot generate the exponential regression. It saves the fitted variables in a file that pgfplots should read and pretty-print in the plot legend. It works as intended for variables b and c but not for a.

At first I thought it was related to the number not being rendered in scientific notation, but forcing it through \pgfmathprintnumber[sci] still outputs wrongly, which leads me to believe the problem lies with the gnuplot interaction.

I want the first graph to have the same legend as the second, but still have it be generated as I’m using this in a macro for different sets of data. What should I do?

Minimal example:

\documentclass{article}
\usepackage{pgfplotstable}

\begin{filecontents}{data.csv}
x,  y
2,  0.000058
3,  0.001888
4,  0.058763
5,  1.78986
\end{filecontents}

\begin{document}

\begin{figure}[H]
\centering
\begin{tikzpicture}
    \begin{axis}
    \addplot [raw gnuplot, smooth] gnuplot {
        f(x)=(a)*(b^(c*x));
        a=6.8e-8;
        b=2.7;
        c=3.4;
        fit f(x) 'data.csv' using 1:2 via a,b,c;
        plot f(x);
        set print "data.csv.dat";
        print a,b,c;
    };
    \addlegendentry{
        \pgfplotstableread{data.csv.dat}\parameters
        \pgfplotstablegetelem{0}{0}\of\parameters \pgfmathsetmacro{\paramA}{\pgfplotsretval}
        \pgfplotstablegetelem{0}{1}\of\parameters \pgfmathsetmacro{\paramB}{\pgfplotsretval}
        \pgfplotstablegetelem{0}{2}\of\parameters \pgfmathsetmacro{\paramC}{\pgfplotsretval}
        $y=\pgfmathprintnumber[sci]{\paramA} \cdot \pgfmathprintnumber{\paramB}^{\pgfmathprintnumber{\paramC} \cdot x}$
    }
    \end{axis}
\end{tikzpicture}
\end{figure}

\begin{figure}[H]
\centering
\begin{tikzpicture}
    \begin{axis}
    \addplot [raw gnuplot, smooth] gnuplot {
        plot (6.82564001285694e-08)*(2.71554805209898^(3.41986746643527*x));
    };
    \addlegendentry{
        $y=\pgfmathprintnumber{6.82564002501364e-08} \cdot \pgfmathprintnumber{2.71554805209898}^{\pgfmathprintnumber{3.41986746643527} \cdot x}$
    }
    \end{axis}
\end{tikzpicture}
\end{figure}

\end{document}

Result:

data.csv.dat.

6.82564001285694e-08 2.71565816582345 3.41972869952421

erroneous plot:

erroneous plot

desired plot:

desired plot

  • 1
    According to the manual of pgfplotstable, the precision is limited to 10^{-6} – user31729 Mar 21 '15 at 14:26
  • In addition, this has nothing to do with gnuplot or not. It's a pgf feature – user31729 Mar 21 '15 at 14:39
  • Would it be possible to alter this by manually copying and editing the .sty file? Maybe do it on-the-fly if that’s possible? – user74027 Mar 21 '15 at 14:41
  • You could run the fit data through (for example) sed and format it so you separate the exponent from the factor and reduce the precision of the numbers. Or look into gnuplot if you could change the output format there... – jens_bo Mar 21 '15 at 14:51
  • @jens_bo: The problem isn't the format, it's the small value in fact – user31729 Mar 21 '15 at 15:58
2

Changing the gnuplot output is probably the easiest way to do it and circumvent the precision limitation of pgfplots.

a/10^floor(log10(a)),floor(log10(a)) gives you the parts of the scientific notation in two separate columns. Those can be read into pgfplots and put into the legend.

\begin{tikzpicture}
  \begin{axis}
   \addplot [raw gnuplot, smooth] gnuplot {
    f(x)=(a)*(b^(c*x));
    a=6.8e-8;
    b=2.7;
    c=3.4;
    fit f(x) 'data.csv' using 1:2 via a,b,c;
    plot f(x);
    set print "data.csv.dat";
    print a/10^floor(log10(a)),floor(log10(a)),b,c;};
   \addlegendentry{
    \pgfplotstableread{data.csv.dat}\parameters
    \pgfplotstablegetelem{0}{0}\of\parameters \pgfmathsetmacro{\paramAa}{\pgfplotsretval}
    \pgfplotstablegetelem{0}{1}\of\parameters \pgfmathsetmacro{\paramAb}{\pgfplotsretval}
   \pgfplotstablegetelem{0}{2}\of\parameters
   \pgfmathsetmacro{\paramB}{\pgfplotsretval}
   \pgfplotstablegetelem{0}{3}\of\parameters \pgfmathsetmacro{\paramC}{\pgfplotsretval}
   $y=\pgfmathprintnumber{\paramAa}\cdot 10^{\paramAb} \cdot \pgfmathprintnumber{\paramB}^{\pgfmathprintnumber{\paramC} \cdot x}$
}
 \end{axis}
\end{tikzpicture}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy