29 Creating Plots

This section describes the pgfbaseplot package.

\usepackage{pgfbaseplot} % LATEX
\input pgfbaseplot.tex % plain TEX
\input pgfbaseplot.tex % ConTEXt

This package provides a set of commands that are intended to make it reasonably easy to plot functions using PGF. It is loaded automatically by pgf, but you can load it manually if you have only included pgfcore.

29.1 Overview

29.1.1 When Should One Use PGF for Generating Plots?

There exist many powerful programs that produce plots, examples are GNUPLOT or MATHEMATICA. These programs can produce two different kinds of output: First, they can output a complete plot picture in a certain format (like PDF) that includes all low-level commands necessary for drawing the complete plot (including axes and labels). Second, they can usually also produce “just plain data” in the form of a long list of coordinates. Most of the powerful programs consider it a to be “a bit boring” to just output tabled data and very much prefer to produce fancy pictures. Nevertheless, when coaxed, they can also provide the plain data.

The plotting mechanism described in the following deals only with plotting data given in the form of a list of coordinates. Thus, this section is about using PGF to turn lists of coordinates into plots.

Note that is often not necessary to use PGF for this. Programs like GNUPLOT can produce very sophisticated plots and it is usually much easier to simply include these plots as a finished PDF or PostScript graphics.

However, there are a number of reasons why you may wish to invest time and energy into mastering the PGF commands for creating plots:

The above list is not exhaustive, unfortunately.

29.1.2 How PGF Handles Plots

PGF (conceptually) uses a two-stage process for generating plots. First, a plot stream must be produced. This stream consists (more or less) of a large number of coordinates. Second a plot handler is applied to the stream. A plot handler “does something” with the stream. The standard handler will issue line-to operations to the coordinates in the stream. However, a handler might also try to issue appropriate curve-to operations in order to smooth the curve. A handler may even do something else entirely, like writing each coordinate to another stream, thereby duplicating the original stream.

Both for the creation of streams and the handling of streams different sets of commands exist. The commands for creating streams start with \pgfplotstream, the commands for setting the handler start with \pgfplothandler.

29.2 Generating Plot Streams

29.2.1 Basic Building Blocks of Plot Streams

A plot stream is a (long) sequence of the following three commands:

  1. \pgfplotstreamstart,
  2. \pgfplotstreampoint, and
  3. \pgfplotstreamend.

Between calls of these commands arbitrary other code may be called. Obviously, the stream should start with the first command and end with the last command. Here is an example of a plot stream:


\pgfplotstreamstart
\pgfplotstreampoint{\pgfpoint{1cm}{1cm}}
\newdimen\mydim
\mydim=2cm
\pgfplotstreampoint{\pgfpoint{\mydim}{2cm}}
\advance \mydim by 3cm
\pgfplotstreampoint{\pgfpoint{\mydim}{2cm}}
\pgfplotstreamend

\pgfplotstreamstart

This command signals that a plot stream starts. The effect of this command is to call the internal command \pgf@plotstreamstart, which is set by the current plot handler to do whatever needs to be done at the beginning of the plot.

\pgfplotstreampoint{<point>}

This command adds a <point> to the current plot stream. The effect of this command is to call the internal command \pgf@plotstreampoint, which is also set by the current plot handler. This command should now “handle” the point in some sensible way. For example, a line-to command might be issued for the point.

\pgfplotstreamend

This command signals that a plot stream ends. It calls \pgf@plotstreamend, which should now do any necessary “cleanup.”

Note that plot streams are not buffered, that is, the different points are handled immediately. However, using the recording handler, it is possible to record a stream.

29.2.2 Commands That Generate Plot Streams

Plot streams can be created “by hand” as in the earlier example. However, most of the time the coordinates will be produced internally by some command. For example, the \pgfplotxyfile reads a file and converts it into a plot stream.

\pgfplotxyfile{<filename>}

This command will try to open the file <filename>. If this succeeds, it will convert the file contents into a plot stream as follows: A \pgfplotstreamstart is issued. Then, each nonempty line of the file should start with two numbers separated by a space, such as 0.1 1 or 100 -.3. Anything following the numbers is ignored.

Each pair <x> and <y> of numbers is converted into one plot stream point in the xy-coordinate system. Thus, a line like


2 -5 some text

is turned into


\pgfplotstreampoint{\pgfpointxy{2}{-5}}

The two characters % and # are also allowed in a file and they are both treated as comment characters. Thus, a line starting with either of them is empty and, hence, ignored.

When the file has been read completely, \pgfplotstreamend is called.

\pgfplotxyzfile{<filename>}

This command works like \pgfplotxyfile, only three numbers are expected on each non-empty line. They are converted into points in the xyz-coordinate system. Consider, the following file:


% Some comments
# more comments
2 -5  1 first entry
2 -.2 2 second entry
2 -5  2 third entry

It is turned into the following stream:


\pgfplotstreamstart
\pgfplotstreampoint{\pgfpointxyz{2}{-5}{1}}
\pgfplotstreampoint{\pgfpointxyz{2}{-.2}{2}}
\pgfplotstreampoint{\pgfpointxyz{2}{-5}{2}}
\pgfplotstreamend

Currently, there is no command that can decide automatically whether the xy-coordinate system should be used or whether the xyz-system should be used. However, it would not be terribly difficult to write a “smart file reader” that parses coordinate files a bit more intelligently.

\pgfplotgnuplot[<prefix>]{<function>}

This command will “try” to call the GNUPLOT program to generate the coordinates of the <function>. In detail, the following happens:

This command works with two files: <prefix>.gnuplot and <prefix>.table. If the optional argument <prefix> is not given, it is set to \jobname.

Let us start with the situation where none of these files exists. Then PGF will first generate the file <prefix>.gnuplot. In this file it writes


set terminal table; set output "#1.table"; set format "%.5f"

where #1 is replaced by <prefix>. Then, in a second line, it writes the text <function>.

Next, PGF will try to invoke the program gnuplot with the argument <prefix>.gnuplot. This call may or may not succeed, depending on whether the \write18 mechanism (also known as shell escape) is switched on and whether the gnuplot program is available.

Assuming that the call succeeded, the next step is to invoke \pgfplotxyfile on the file <prefix>.table; which is exactly the file that has just been created by gnuplot.

 

SVG-Viewer needed.

 

\begin{tikzpicture}
  \draw[help lines] (0,-1) grid (4,1);
  \pgfplothandlerlineto
  \pgfplotgnuplot[plots/pgfplotgnuplot-example]{plot [x=0:3.5] x*sin(x)}
  \pgfusepath{stroke}
\end{tikzpicture}

The more difficult situation arises when the .gnuplot file exists, which will be the case on the second run of TEX on the TEX file. In this case PGF will read this file and check whether it contains exactly what PGF “would have written” into this file. If this is not the case, the file contents is overwritten with what “should be there” and, as above, gnuplot is invoked to generate a new .table file. However, if the file contents is “as expected,” the external gnuplot program is not called. Instead, the <prefix>.table file is immediately read.

As explained in Section 9.12.3, the net effect of the above mechanism is that gnuplot is called as little as possible and that when you pass along the .gnuplot and .table files with your .tex file to someone else, that person can TEX the .tex file without having gnuplot installed and without having the \write18 mechanism switched on.

29.3 Plot Handlers

A plot handler prescribes what “should be done” with a plot stream. You must set the plot handler before the stream starts. The following commands install the most basic plot handlers; more plot handlers are defined in the file pgflibraryplothandlers, which is documented in Section 14.3.

All plot handlers work by setting redefining the following three macros: \pgf@plotstreamstart, \pgf@plotstreampoint, and \pgf@plotstreamend.

\pgfplothandlerlineto

This handler will issue a \pgfpathlineto command for each point of the plot, except possibly for the first. What happens with the first point can be specified using the two commands described below.

 

SVG-Viewer needed.

 

\begin{pgfpicture}
  \pgfpathmoveto{\pgfpointorigin}
  \pgfplothandlerlineto
  \pgfplotstreamstart
  \pgfplotstreampoint{\pgfpoint{1cm}{0cm}}
  \pgfplotstreampoint{\pgfpoint{2cm}{1cm}}
  \pgfplotstreampoint{\pgfpoint{3cm}{2cm}}
  \pgfplotstreampoint{\pgfpoint{1cm}{2cm}}
  \pgfplotstreamend
  \pgfusepath{stroke}
\end{pgfpicture}

\pgfsetmovetofirstplotpoint

Specifies that the line-to plot handler (and also some other plot handlers) should issue a move-to command for the first point of the plot instead of a line-to. This will start a new part of the current path, which is not always, but often, desirable. This is the default.

\pgfsetlinetofirstplotpoint

Specifies that plot handlers should issue a line-to command for the first point of the plot.

 

SVG-Viewer needed.

 

\begin{pgfpicture}
  \pgfpathmoveto{\pgfpointorigin}
  \pgfsetlinetofirstplotpoint
  \pgfplothandlerlineto
  \pgfplotstreamstart
  \pgfplotstreampoint{\pgfpoint{1cm}{0cm}}
  \pgfplotstreampoint{\pgfpoint{2cm}{1cm}}
  \pgfplotstreampoint{\pgfpoint{3cm}{2cm}}
  \pgfplotstreampoint{\pgfpoint{1cm}{2cm}}
  \pgfplotstreamend
  \pgfusepath{stroke}
\end{pgfpicture}

\pgfplothandlerdiscard

This handler will simply throw away the stream.

\pgfplothandlerrecord{<macro>}

When this handler is installed, each time a plot stream command is called, this command will be appended to <macros>. Thus, at the end of the stream, <macro> will contain all the commands that were issued on the stream. You can then install another handler and invoke <macro> to “replay” the stream (possibly many times).

 

SVG-Viewer needed.

 

\begin{pgfpicture}
  \pgfplothandlerrecord{\mystream}
  \pgfplotstreamstart
  \pgfplotstreampoint{\pgfpoint{1cm}{0cm}}
  \pgfplotstreampoint{\pgfpoint{2cm}{1cm}}
  \pgfplotstreampoint{\pgfpoint{3cm}{1cm}}
  \pgfplotstreampoint{\pgfpoint{1cm}{2cm}}
  \pgfplotstreamend
  \pgfplothandlerlineto
  \mystream
  \pgfplothandlerclosedcurve
  \mystream
  \pgfusepath{stroke}
\end{pgfpicture}