# pgfplots: post-processing data created with gnuplot

I have managed to use pgfplots' gnuplot option to solve an implicit equation:

\documentclass{standalone}

\usepackage{tikz,pgfplots}

\begin{document}
\begin{tikzpicture}
\begin{loglogaxis}[
xmin=8e2,
xmax=1e8,
ymin=0.008,
ymax=0.1
]
set xrange [2300:1e8];
set yrange [0.008:0.1];
set logscale xy;
set samples 100;
f(R,L) = -2*log10(2.51/(R*sqrt(L))+4e-3/3.71)-1/sqrt(L);
set cont base;
set cntrparam levels discrete 0;
unset surface;
splot f(x,y)
};
\end{loglogaxis}
\end{tikzpicture}
\end{document}


The problem here is that gnuplot doesn't sort the result, so that the plot appears closed. How can I sort the data generated by gnuplot before it is plotted by pgfplots?

I have tried to pass table sorting options to gnuplot:

\addplot[...] gnuplot[sort=true,sort cmp={float <}] {...};


which didn't work.

My other idea was to call gnuplot from my tex document without plotting immediately. I could then read the data with pgfplotstable and process it, but I don't know a convenient way to call gnuplot. My goal is to generate a number of plots in one axis environment only with one call to pfdlatex.

I noticed that pgfplots 1.5.1 does not close the plot, but pgfplots 1.4.1 does. However, the coordinates are still not sorted and the nodes current plot end and current plot begin are at the same coordinate (which is bad in my case).

-
I don't think this can easily be done, since in general, there's no natural order for the points in a contour plot: They could be (and frequently are) closed polygons, so it's not obvious to which point (current plot end) should refer. – Jake Feb 11 '12 at 11:41
@Jake in general, you are right. In this particular case, sorting may be useful to close the plot. – Christian Feuersänger Feb 12 '12 at 16:55
Does pgfplots interpret contour plots made with gnuplot as contour plots at all? – Christoph Feb 13 '12 at 8:29

You have two questions if I am not mistaken:

Question 1. How can I sort the result of gnuplot?

Question 2. Why is there a difference between version 1.4 and 1.5 ?

Question 1. You can sort the result only using macros from pgfplotstable. The sort option is only for \pgfplotstabletypeset. It works if you allow two passes of pdflatex:

\begin{tikzpicture}
\IfFileExists{P.pgf-plot.table}{
\pgfplotstablesort{\DATA}{P.pgf-plot.table}
}{}

\begin{loglogaxis}
\IfFileExists{P.pgf-plot.table}{
}{
set xrange [2300:1e8];
set yrange [0.008:0.1];
set logscale xy;
set samples 100;
f(R,L) = -2*log10(2.51/(R*sqrt(L))+4e-3/3.71)-1/sqrt(L);
set cont base;
set cntrparam levels discrete 0;
unset surface;
splot f(x,y)
};
}
\end{loglogaxis}
\end{tikzpicture}


The key idea is to use \IfFileExists to distinguish between first and second run - and to use \pgfplotstablesort to load the sorted table into \DATA. Plotting it does what you wanted.

ATTENTION: I used P.tex as my main tex file name. You need to adjust it.

Note that the experiment revealed a small bug in pgfplots: moving the \pgfplotstablesort macro into the axis fails. I will fix that (there is a callback which should not be active).

A suitable modification would be to write a temporary file containing the gnuplot script and run gnuplot manually using \write18{gnuplot datafilename}.

Question 2. Starting with version 1.5, pgfplots will close gaps in plots -- unless one uses \pgfplotsset{compat=1.4} or newer, in which case it will not close them.

The new feature allows to add empty lines into a data files in order to define piecewise functions (i.e. pgfplots will generate a gap at empty lines).

The use of \pgfplotsset{compat=1.3} will restore the old handling and close the gap.

-
Using \write18 to call gnuplot was a good idea! I now use \write to store my gnuplot options (like it is done by pgfplots), \write18 to call gnuplot and post-processing tools, and then plot the result with \addplot table. – Christoph Feb 13 '12 at 9:00

Here is a partial solution derived from the answer by Christian. The major drawback is that the data cannot be sorted (and therefore generated) in the loglogaxis environment, because pgfplotstablesave is not known there.

\documentclass{standalone}

\usepackage{tikz}
\usepackage{pgfplots}
\usepackage{pgfplotstable}

\makeatletter
\newcommand{\gnuplotOptions}[2][pgf-plot]{%
\newwrite\tempfile%
\immediate\openout\tempfile=\jobname.#1.gnuplot%
\immediate\write\tempfile{set table "\jobname.#1.table";}%
\immediate\write\tempfile{set format "\@percentchar.7e";}%
\immediate\write\tempfile{#2}%
\immediate\closeout\tempfile%
}
\makeatother

\newcommand{\gnuplot}[1][pgf-plot]{%
\immediate\write18{gnuplot \jobname.#1.gnuplot}%
}

\begin{document}
\begin{tikzpicture}
\gnuplotOptions{%
set xrange [2300:1e8];
set yrange [0.008:0.1];
set logscale xy;
set samples 100;
f(R,L) = -2*log10(2.51/(R*sqrt(L))+4e-3/3.71)-1/sqrt(L);
set cont base;
set cntrparam levels discrete 0;
unset surface;
splot f(x,y);
}
\gnuplot{}
\pgfplotstablesave[sort=true,sort cmp={float <}]{\jobname.pgf-plot.table}{\jobname.pgf-plot.sorted.table}
\begin{loglogaxis}
% cannot create and sort the table here because pgfplotstablesave is unknown in the axis environment (pgfplots 1.5)
\addplot[raw gnuplot] table[x index=0, y index=1] {\jobname.pgf-plot.sorted.table};
\end{loglogaxis}
\end{tikzpicture}
\end{document}


The gnuplotOptions command accepts one optional argument which behaves like pgfplots's id key. All options are written to an option file for gnuplot. This key can also be passed to gnuplot by using \gnuplot[someid]{} to make gnuplot find the right option file.

\pgfplotstablesave creates a copy of the table generated with gnuplot and writed the sorted table back to a new file.

The result is plotted as usual with \addplot table.

-