[Tex/LaTex] GnuplotTex: automatic plotting and vertical line indication

gnuplot

I am using pdflatex with the gnuplottex package, to plot a function with a local maximum; I'd like to find this maximum automatically and label it.

For the most part, I'm already there (using the special "pseudo" file '+' in gnuplot >4.4), apart from a couple of problems — and I'm not sure whether the problem is in LaTeX or gnuplot … Here is a minimal working example:

% build with:
% pdflatex -shell-escape test.tex

\documentclass{article}
\makeatletter\newwrite\verbatim@out\makeatother
\usepackage{gnuplottex}

\begin{document}

\section{Test}

Here a brief test...

\begin{figure}[h]
\centering
\begin{gnuplot}[scale=0.95]
  # Define helper functions
  ismax(x) = (x>max)?max=x:0
  isxmax(x) = (ismax(f(x))!=0)?xmax=x:0 #

  # Initialise the 'global' vars
  max=-1e38
  xmax=-1e38
  min=1e38
  ymaxrange=0.05 # added

  set grid
  set title 'gnuplottex test'
  set ylabel '$y$'
  set xlabel '$x$'
  set xrange [0:2000]
  set yrange [0:ymaxrange] # MUST set this!

  # define the function
  f(x) = (20*x)/(100000 + 50*x + x**2)

  set multiplot

  # plot f(x) # OK, works as usual

  # to turn off the annoying label in the upper right corner - also f($0) will cause latex crash
  set nokey

  # plot the function - which will also calculate xmax (first pass)

  plot '+' using ($1):(f($1)) with linespoints,       '+' using ($1):(isxmax($1)) with lines linecolor 2
  # '+' using ($1):(ismax(f($1))) with lines linecolor 2


  # second part of plot - which needs xmax

  set grid noxtics noytics # prevent double plot ?!
  set arrow from xmax,0 to xmax,3 nohead lt 1 linewidth 2 # linewidth doesn't change ?!

  set label "X" at xmax,f(xmax)
  set label "(%.0f;",xmax,"%f)",f(xmax) at 0.6*xmax,f(xmax)+ymaxrange/10

  plot '+' using ($1)
  # replot # nope, doubles
  unset multiplot
\end{gnuplot}
\end{figure}


500 1000 1500 ... End of test.

\end{document}

This code results with a rendering like this (which is a screenshot of evince rendering the PDF):

gnuplottex test

And these are my problems:

  • It seems that upon execution of the second plot, the labels and axes get repeated on top of each other, in spite of a set grid noxtics noytics (notice they are a bit darker in the screenshot) — can this be prevented?
  • In principle, without the set yrange ... line, the second plot may contain a different automatic range (though that is not visible in this example). Is there a way to "copy"/duplicate a range of an axis that was computed automatically in gnuplot?
  • the linewidth (lw) argument of set arrow (which is for implementing a vertical line) seems not to have any effect — how can I manipulate that?
  • The line from set arrow and the (very thin dotted) line from the isxmax($1) plot do not match; seemingly it is the arrow that is off — how to fix this?
  • The linecolor argument seems to have no effect — how to fix this? (btw, color seems to work fine for \begin{gnuplot}[terminal=pdf,..., however, I'd like to keep the LaTeX 'terminal')

References:

Best Answer

I would use the pgfplots package for this. You can generate the data with gnuplot by using \addplot gnuplot {<expression>};, and then read the generated data using \pgfplotstableread{\jobname.pgf-plot.table}\table. After sorting this table, you just access the first element, which now contains the local maximum.

\documentclass{article}
\usepackage{pgfplots}
\usepackage{pgfplotstable}
\begin{document}

\begin{tikzpicture}
\begin{axis}[ymin=0,ymax=0.05,xmin=0,xmax=2000,grid=both]

\addplot [domain={0:2000},samples=1000]
  gnuplot {(20*x)/(100000 + 50*x + x**2)};

\pgfplotstableread{\jobname.pgf-plot.table}\table
\pgfplotstablesort[sort cmp={float >},sort key={[index] 1}]\sorted{\table}
\pgfplotstablegetelem{0}{[index] 1}\of{\sorted}
\let\maxy=\pgfplotsretval
\pgfplotstablegetelem{0}{[index] 0}\of{\sorted}
\let\maxx=\pgfplotsretval


\node at (axis cs:\maxx,\maxy)
  [circle, fill, red,inner sep=1.5pt,
   pin={
    [fill=white]40:{(\pgfmathprintnumber{\maxx}, \pgfmathprintnumber{\maxy}})
   }
  ] {};
\draw [red] (axis cs:\maxx,0) -- (axis cs:\maxx,1);
\end{axis}
\end{tikzpicture}

\end{document}

finding the local maximum using pgpflots