tikz.dev / PGFplots Manual

Manual for Package pgfplots
2D/3D Plots in LA, Version 1.18.1
http://sourceforge.net/projects/pgfplots

The Reference

\(\newcommand{\footnotename}{footnote}\) \(\def \LWRfootnote {1}\) \(\newcommand {\footnote }[2][\LWRfootnote ]{{}^{\mathrm {#1}}}\) \(\newcommand {\footnotemark }[1][\LWRfootnote ]{{}^{\mathrm {#1}}}\) \(\let \LWRorighspace \hspace \) \(\renewcommand {\hspace }{\ifstar \LWRorighspace \LWRorighspace }\) \(\newcommand {\mathnormal }[1]{{#1}}\) \(\newcommand \ensuremath [1]{#1}\) \(\newcommand {\LWRframebox }[2][]{\fbox {#2}} \newcommand {\framebox }[1][]{\LWRframebox } \) \(\newcommand {\setlength }[2]{}\) \(\newcommand {\addtolength }[2]{}\) \(\newcommand {\setcounter }[2]{}\) \(\newcommand {\addtocounter }[2]{}\) \(\newcommand {\arabic }[1]{}\) \(\newcommand {\number }[1]{}\) \(\newcommand {\noalign }[1]{\text {#1}\notag \\}\) \(\newcommand {\cline }[1]{}\) \(\newcommand {\directlua }[1]{\text {(directlua)}}\) \(\newcommand {\luatexdirectlua }[1]{\text {(directlua)}}\) \(\newcommand {\protect }{}\) \(\def \LWRabsorbnumber #1 {}\) \(\def \LWRabsorbquotenumber "#1 {}\) \(\newcommand {\LWRabsorboption }[1][]{}\) \(\newcommand {\LWRabsorbtwooptions }[1][]{\LWRabsorboption }\) \(\def \mathchar {\ifnextchar "\LWRabsorbquotenumber \LWRabsorbnumber }\) \(\def \mathcode #1={\mathchar }\) \(\let \delcode \mathcode \) \(\let \delimiter \mathchar \) \(\def \oe {\unicode {x0153}}\) \(\def \OE {\unicode {x0152}}\) \(\def \ae {\unicode {x00E6}}\) \(\def \AE {\unicode {x00C6}}\) \(\def \aa {\unicode {x00E5}}\) \(\def \AA {\unicode {x00C5}}\) \(\def \o {\unicode {x00F8}}\) \(\def \O {\unicode {x00D8}}\) \(\def \l {\unicode {x0142}}\) \(\def \L {\unicode {x0141}}\) \(\def \ss {\unicode {x00DF}}\) \(\def \SS {\unicode {x1E9E}}\) \(\def \dag {\unicode {x2020}}\) \(\def \ddag {\unicode {x2021}}\) \(\def \P {\unicode {x00B6}}\) \(\def \copyright {\unicode {x00A9}}\) \(\def \pounds {\unicode {x00A3}}\) \(\let \LWRref \ref \) \(\renewcommand {\ref }{\ifstar \LWRref \LWRref }\) \( \newcommand {\multicolumn }[3]{#3}\) \(\require {textcomp}\) \( \newcommand {\meta }[1]{\langle \textit {#1}\rangle } \) \(\newcommand {\toprule }[1][]{\hline }\) \(\let \midrule \toprule \) \(\let \bottomrule \toprule \) \(\def \LWRbooktabscmidruleparen (#1)#2{}\) \(\newcommand {\LWRbooktabscmidrulenoparen }[1]{}\) \(\newcommand {\cmidrule }[1][]{\ifnextchar (\LWRbooktabscmidruleparen \LWRbooktabscmidrulenoparen }\) \(\newcommand {\morecmidrules }{}\) \(\newcommand {\specialrule }[3]{\hline }\) \(\newcommand {\addlinespace }[1][]{}\) \(\require {colortbl}\) \(\let \LWRorigcolumncolor \columncolor \) \(\renewcommand {\columncolor }[2][named]{\LWRorigcolumncolor [#1]{#2}\LWRabsorbtwooptions }\) \(\let \LWRorigrowcolor \rowcolor \) \(\renewcommand {\rowcolor }[2][named]{\LWRorigrowcolor [#1]{#2}\LWRabsorbtwooptions }\) \(\let \LWRorigcellcolor \cellcolor \) \(\renewcommand {\cellcolor }[2][named]{\LWRorigcellcolor [#1]{#2}\LWRabsorbtwooptions }\) \(\newcommand {\intertext }[1]{\text {#1}\notag \\}\) \(\let \Hat \hat \) \(\let \Check \check \) \(\let \Tilde \tilde \) \(\let \Acute \acute \) \(\let \Grave \grave \) \(\let \Dot \dot \) \(\let \Ddot \ddot \) \(\let \Breve \breve \) \(\let \Bar \bar \) \(\let \Vec \vec \) \(\newcommand {\nicefrac }[3][]{\mathinner {{}^{#2}\!/\!_{#3}}}\)

4.6Three Dimensional Plot Types

pgfplots provides three dimensional visualizations like scatter, line, mesh or surface plots. This section explains the methods to provide input coordinates and how to use the different plot types.

4.6.1Before You Start With 3D

Before we delve into the capabilities of pgfplots for three dimensional visualization, let me start with some preliminary remarks. The reason to use pgfplots for three dimensional plots are similar to those of normal, two dimensional plots: the possibility to get consistent fonts and document consistent styles combined with high-quality output.

While this works very nice for (not too complex) two dimensional plots, it requires considerably more effort than non-graphical documents. This is even more so for three dimensional plots. In other words: pgfplots’ three dimensional routines are slow. There are reasons for this and some of them may vanish in future versions. But one of these reasons is that has never been designed for complex visualization techniques. Consider using lualatex (and at least compat=1.12) in order to reduce compilation times and to avoid memory limitations. Also consider the image externalization routines mentioned in Section 8.1, in particular the external library to reduce typesetting time. Besides the speed limitations, three dimensional plots reach memory limits easily. Therefore, the plot complexity of three dimensional plots is limited to relatively coarse resolutions. Section 8.1 also discusses methods to extend the initial memory limits.

Another issue which arises in three dimensional visualization is depth: it is necessary to decide which items are to be drawn in front of others. pgfplots supports \(z\) buffering techniques up to a certain extend: it works pretty well for single scatter plots (z buffer=sort), mesh or surface plots (z buffer=auto) or parametric mesh and surface plots (z buffer=sort). However, it cannot combine different \addplot commands, those will be drawn in the order of appearance. You may encounter the limitations sometimes. Maybe it will be improved in future versions.

If you decide that you need high complexity, speed and 100% reliable z buffers (depth information), you should consider using other visualization tools and return to pgfplots in several years. If you can wait for a complex picture and you do not even see the limitations arising from z buffering limitations, you should use pgfplots. Again, consider using the automatic picture externalization with the external library discussed in Section 8.1.

4.6.2The \addplot3 Command: Three Dimensional Coordinate Input
  • \addplot3[(math image)options(math image)] (math image)input data(math image) (math image)trailing path commands(math image);

  • The \addplot3 command is the main interface for any three dimensional plot. It works in the same way as its two dimensional variant \addplot which has been described in all detail in Section 4.3.

    The \addplot3 command accepts the same input methods as the \addplot variant, including expression plotting, coordinates, files and tables. However, a third coordinate is necessary for each of these methods which is usually straightforward and is explained in all detail in the following.

    Furthermore, \addplot3 has a way to decide whether a line visualization or a mesh visualization has to be done. The first one is a map from one dimension into \(\mathbb {R}^3\) and the latter one a map from two dimensions to \(\mathbb {R}^3\). Here, the keys mesh/rows and mesh/cols are used to define mesh sizes (matrix sizes). Usually, you don’t have to care about that because the coordinate input routines already allow either one- or two-dimensional structure.

    The precise rules how pgfplots distinguishes between line visualization and mesh visualization is as follows:

  • \addplot3 coordinates {(math image)coordinate list(math image)};

  • \addplot3[(math image)options(math image)] coordinates {(math image)coordinate list(math image)} (math image)trailing path commands(math image);

  • The \addplot3 coordinates method works like its two-dimensional variant, \addplot coordinates which is described in all detail at 31:

    A long list of coordinates ((math image)x(math image),(math image)y(math image),(math image)z(math image)) is expected, separated by white spaces. The input list can be either an unordered series of coordinates, for example for scatter or line plots. It can also have matrix structure, in which case an empty line (which is equivalent to “\par”) marks the end of one matrix row. Matrix structure can also be provided if one of mesh/rows or mesh/cols is provided explicitly.

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} % this yields a 3x4 matrix: \addplot3 [surf] coordinates { (0,0,0) (1,0,0) (2,0,0) (3,0,0) (0,1,0) (1,1,0.6) (2,1,0.7) (3,1,0.5) (0,2,0) (1,2,0.7) (2,2,0.8) (3,2,0.5) }; \end{axis} \end{tikzpicture}

    Here, \addplot3 reads a matrix with three rows and four columns. The empty lines separate one row from the following.

    As for the two-dimensional \addplot coordinates, it is possible to provide (constant) mathematical expressions inside of single coordinates. The syntax ((math image)x(math image),(math image)y(math image),(math image)z(math image)) [(math image)meta(math image)] can be used just as for two dimensional \addplot coordinates to provide explicit color data; error bars are also supported.

  • \addplot3 table [(math image)column selection(math image)]{(math image)file(math image)};

  • \addplot3[(math image)options(math image)] table [(math image)column selection(math image)]{(math image)file(math image)} (math image)trailing path commands(math image);

  • The \addplot3 table input works in the same way as its two dimensional counterpart \addplot table. It only expects a column for the \(z\)-coordinates.

    As for \addplot3 coordinates, an empty line in the file marks the end of one matrix row.

    For matrix data in files, it is important to specify the ordering in which the matrix entries have been written. The default configuration is mesh/ordering=x varies, so you need to change it to mesh/ordering=y varies in case you have column by column ordering.

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} % this yields a 3x4 matrix: \addplot3 [surf] table { 0 0 0 1 0 0 2 0 0 3 0 0 0 1 0 1 1 0.6 2 1 0.7 3 1 0.5 0 2 0 1 2 0.7 2 2 0.8 3 2 0.5 }; \end{axis} \end{tikzpicture}
  • \addplot3 file {(math image)name(math image)};

  • \addplot3[(math image)options(math image)] file {(math image)name(math image)} (math image)trailing path commands(math image);

Deprecation note:

If you have data files, you should generally use \addplot table. The input type \addplot file is almost the same, but considerably less powerful. It is only kept for backwards compatibility.

The \addplot3 file input method is the same as \addplot file – it only expects one more coordinate. Thus, the input file contains \(x_i\) in the first column, \(y_i\) in the second column and \(z_i\) in the third.

A further column is read after \(z_i\) if point meta=explicit has been requested, see the documentation of \addplot file at 147 for details.

As for \addplot3 coordinates, an empty line in the file marks the end of one matrix row.

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} % We have `plotdata/first3d.dat' with % --------- % 0 0 0.8 % 1 0 0.56 % 2 0 0.5 % 3 0 0.75 % % 0 1 0.6 % 1 1 0.3 % 2 1 0.21 % 3 1 0.3 % % 0 2 0.68 % 1 2 0.22 % 2 2 0.25 % 3 2 0.4 % % 0 3 0.7 % 1 3 0.5 % 2 3 0.58 % 3 3 0.9 % -> yields a 4x4 matrix: \addplot3 [surf] file {plotdata/first3d.dat}; \end{axis} \end{tikzpicture}

For matrix data in files, it is important to specify the ordering in which the matrix entries have been written. The default configuration is mesh/ordering=x varies, so you need to change it to mesh/ordering=y varies in case you have column by column ordering.

  • /pgfplots/mesh/rows={(math image)integer(math image)}

  • /pgfplots/mesh/cols={(math image)integer(math image)}

  • For visualization of mesh or surface plots which need some sort of matrix input, the dimensions of the input matrix need to be known in order to visualize the plots correctly. The matrix structure may be known from end-of-row marks (empty lines as general end-of-scanline markers in the input stream) as has been described above.

    If the matrix structure is not yet known, it is necessary to provide at least one of mesh/rows or mesh/cols where mesh/rows indicates the number of samples for \(y\)-coordinates whereas mesh/cols is the number of samples used for \(x\)-coordinates (see also mesh/ordering).

    Thus, the following example is also a valid method to define an input matrix.

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} % this yields also a 3x4 matrix: \addplot3 [surf,mesh/rows=3] coordinates { (0,0,0) (1,0,0) (2,0,0) (3,0,0) (0,1,0) (1,1,0.6) (2,1,0.7) (3,1,0.5) (0,2,0) (1,2,0.7) (2,2,0.8) (3,2,0.5) }; \end{axis} \end{tikzpicture}

    It is enough to supply one of mesh/rows or mesh/cols – the missing value will be determined automatically.

    If you provide one of mesh/rows or mesh/cols, any end-of-row marker seen inside of input files or coordinate streams will be ignored.

  • /pgfplots/mesh/scanline verbose=true|false (initially false)

  • Provides debug messages in the output about end-of-scanline markers.

    The message will tell whether end-of-scanlines have been found and if they are the same.

  • /pgfplots/mesh/ordering=x varies|y varies|rowwise|colwise (initially x varies)

  • Allows to configure the sequence in which matrices (meshes) are read from \addplot3 coordinates, \addplot3 file or \addplot3 table.

    Here, x varies means a sequence of points where \(n\)=mesh/cols successive points have the \(y\)-coordinate fixed. This is intuitive when you write down a function because \(x\) is horizontal and \(y\) vertical. Note that in matrix terminology, \(x\) refers to column indices whereas \(y\) refers to row indices. Thus, x varies is equivalent to rowwise ordering in this sense. This is the initial configuration.

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[mesh/ordering=x varies] % this yields a 3x4 matrix in `x varies' % ordering: \addplot3 [surf] coordinates { (0,0,0) (1,0,0) (2,0,0) (3,0,0) (0,1,0) (1,1,0.6) (2,1,0.7) (3,1,0.5) (0,2,0) (1,2,0.7) (2,2,0.8) (3,2,0.5) }; \end{axis} \end{tikzpicture}

    Note that mesh/ordering is mandatory, even though the size of the matrix can be provided in different ways. The example above uses empty lines to mark scanlines. One could also say mesh/rows=3 and omit the empty lines.

    Consequently, mesh/ordering=y varies provides points such that successive \(m\)=mesh/rows points form a column, i.e. the \(x\)-coordinate is fixed and the \(y\)-coordinate changes. In this sense, y varies is equivalent to colwise ordering, it is actually a matrix transposition.

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[mesh/ordering=y varies] % this yields a 3x4 matrix in column-wise ordering: \addplot3 [surf] coordinates { (0,0,0) (0,1,0) (0,2,0) (1,0,0) (1,1,0.6) (1,2,0.7) (2,0,0) (2,1,0.7) (2,2,0.8) (3,0,0) (3,1,0.5) (3,2,0.5) }; \end{axis} \end{tikzpicture}

    Again, note the subtle difference to the common matrix indexing where a column has the second index fixed. pgfplots refers to the way one would write down a function on a sheet of paper (this is consistent with how Matlab® displays discrete functions with matrices).

  • \addplot3 {(math image)math expression(math image)} ;

  • \addplot3[(math image)options(math image)] {(math image)math expression(math image)} (math image)trailing path commands(math image);

  • Expression plotting also works in the same way as for two dimensional plots. Now, however, a two dimensional mesh is sampled instead of a single line, which may depend on x and y.

    The method \addplot3 {(math image)math expr(math image)} visualizes the function \(f(x,y) = \)(math image)math expr(math image) where \(f \colon [x_1,x_2] \times [y_1,y_2] \to \mathbb {R}\). The interval \([x_1,x_2]\) is determined using the domain key, for example using domain=0:1. The interval \([y_1,y_2]\) is determined using the y domain key. If y domain is empty, \([y_1,y_2] = [x_1,x_2]\) will be assumed. If y domain=0:0 (or any other interval of length zero), it is assumed that the plot does not depend on y (thus, it is a line plot).

    The number of samples in \(x\) direction is set using the samples key. The number of samples in \(y\) direction is set using the samples y key. If samples y is not set, the same value as for \(x\) is used. If samples y\(\,\le 1\), it is assumed that the plot does not depend on y (meaning it is a line plot).

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} % requires \usepgfplotslibrary{colorbrewer} \begin{tikzpicture} \begin{axis}[ colormap/PuBu, ] \addplot3 [surf] {y}; \end{axis} \end{tikzpicture}

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[colorbar] \addplot3 [ surf, faceted color=blue, samples=15, domain=0:1,y domain=-1:1 ] {x^2 - y^2}; \end{axis} \end{tikzpicture}

    Expression plotting sets mesh/rows and mesh/cols automatically; these settings don’t have any effect for expression plotting.

  • \addplot3 expression {(math image)math expression(math image)};

  • \addplot3[(math image)options(math image)] expression {(math image)math expression(math image)} (math image)trailing path commands(math image);

  • The syntax

    \addplot3 {(math image)math expression(math image)};

    as short-hand equivalent for

    \addplot3 expression {(math image)math expression(math image)};

  • \addplot3 ((math image)x expression(math image),(math image)y expression(math image),(math image)z expression(math image)) ;

  • \addplot3[(math image)options(math image)] ((math image)x expression(math image),(math image)y expression(math image),(math image)z expression(math image)) (math image)trailing path commands(math image);

  • A variant of \addplot3 expression which allows to provide different coordinate expressions for the \(x\)-, \(y\)- and \(z\)-coordinates. This can be used to generate parameterized plots.

    Please note that \addplot3 (x,y,x^2) is equivalent to \addplot3 expression {x^2}.

    Note further that since the complete point expression is surrounded by round braces, round braces inside of (math image)\(x\) expression(math image), (math image)\(y\) expression(math image) or (math image)\(z\) expression(math image) need to be treated specially. Surround the expressions (which contain round braces) with curly braces:

    \addplot3 ({(math image)\(x\) expr(math image)}, {(math image)\(y\) expr(math image)}, {(math image)\(z\) expr(math image)});

4.6.3Line Plots

Three dimensional line plots are generated if the input source has no matrix structure. Line plots take the input coordinates and connect them in the order of appearance.

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[ xlabel=$x$, ylabel=$y$, ] \addplot3 coordinates {(0,0,0) (0,0.5,1) (0,1,0)}; \addplot3 coordinates {(0,1,0) (0.5,1,1) (1,1,0)}; \end{axis} \end{tikzpicture}

If there is no value for neither mesh/rows nor mesh/cols or if one of them is 1, pgfplots will draw a line plot. This is also the case if there is no end-of-scanline marker (empty line) in the input stream.

For \addplot3 expression, this requires to set samples y=1 to disable the generation of a mesh.

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[view={60}{30}] \addplot3+ [ domain=0:5*pi, samples=60, samples y=0, ] ( {sin(deg(x))}, {cos(deg(x))}, {2*x/(5*pi)} ); \end{axis} \end{tikzpicture}

The example above is a parametric plot by expression, i.e. it has three distinct expressions for \(x\), \(y\), and \(z\).

Line plots in three dimensions are also possible for data plots (tables). The most simple case is if you simply provide a series of three-dimensional coordinates which will be connected in the order of appearance:

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} \addplot3 table { x y z 0 0 0 0.1 0.1 0.1 0.1 0.2 0.2 0.3 0.3 0.3 1 1 1 }; \end{axis} \end{tikzpicture}

Note that this plot implicitly has mesh/rows=1 because it has no end-of-scanline markers (empty lines). If in doubt, you can set mesh/rows=1 explicitly to tell pgfplots that you have one-dimensional data (and not a matrix).

Line plots from data files are also possible if the data files only contains two coordinates – and the third should be provided somehow. In this case, the table/x expr feature comes into play: it allows to combine data plots and math expressions:

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[ xmin=3,xmax=6, extra x ticks={4,5}, extra x tick style={xticklabel=\empty,grid=major} ] \addplot3 table [x expr=4,y=a,z=b] { a b -3 9 -2 4 -1 1 0 0 1 1 2 4 3 9 }; \addplot3 [red,domain=-3:3,samples y=1] (5,x,x^2); \end{axis} \end{tikzpicture}

Here, we have two plots in one axis: one data plot from a data table with just two coordinates and one parametric plot. Both denote the same two functions. For the data plot, x expr=4 assigns the \(x\)-coordinate, and y=a,z=b define how the input columns map to coordinates. Again, the plot implicitly uses mesh/rows=1 since there is no end-of-scanline marker. The second plot does the same with the short-handed notation (5,x,x^2). It only samples one-dimensional data due to samples y=1. Finally, extra x ticks configures two additional ticks for the \(x\)-axis; this is used to display grid lines for these specific ticks. The xticklabel=\empty argument avoids overprinted \(x\) tick labels at positions \(x\in \{4,5\}\).

Three dimensional line plots will usually employ lines to connect points (i.e. the initial sharp plot handler of TikZ). The smooth method of TikZ might also prove be an option. Note that no piecewise constant plot, comb or bar plot handler is supported for three dimensional axes.

4.6.3.1Filled Lined Plots in 3D

Closing a line plot is also possible for three-dimensional axes. This works in the same way as outlined in Section 4.5.11 for two-dimensional axes: by using \closedcycle.

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \pgfplotstableread{ plot1 plot2 plot3 plot4 0.0045 0.0029 0.0089 0.0001 0.0024 0.0023 0.0050 0.0016 0.0007 0.0012 0.0010 0.0001 0.0000 0.0004 -0.0000 -0.0015 0.0001 0.0001 0.0007 -0.0021 0.0003 0.0000 0.0015 -0.0020 0.0003 0.0001 0.0017 -0.0018 0.0003 0.0001 0.0016 -0.0015 0.0003 0.0001 0.0016 -0.0013 0.0003 0.0002 0.0015 -0.0012 }\tabledata \begin{axis}[ zmin=-0.001, area plot/.style={ fill opacity=0.75, draw=orange!80!black,thick, fill=orange, mark=none, }, ytick={1,...,4}, yticklabel=plot\pgfmathprintnumber{\tick}, ] \pgfplotsinvokeforeach{4,3,...,1}{ \addplot3 [area plot] table [ x expr=\coordindex, y expr=#1, z=plot#1, ] {\tabledata} \closedcycle; } \end{axis} \end{tikzpicture}

The difference here is that pgfplots will connect the first and last coordinates on the \(z=0\) plane, or, if \(z=0\) is outside of the axis limits, on the plane \(z_{\min }\).

4.6.4Scatter Plots

Three dimensional scatter plots have the same interface as for two dimensional scatter plots, so all examples of Section 4.5.12 can be used for the three dimensional case as well. The key features are to use only marks and/or scatter as plot styles.

We provide some more examples which are specific for the three dimensional case.

Our first example uses only marks to place the current plot mark at each input position:

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[ xlabel=$x$, ylabel=$y$, zlabel={$f(x,y) = x\cdot y$}, title=A Scatter Plot Example, ] % `pgfplotsexample4_grid.dat' contains a % large sequence of input points of the form % x_0 x_1 f(x) % 0 0 0 % 0 0.03125 0 % 0 0.0625 0 % 0 0.09375 0 % 0 0.125 0 % 0 0.15625 0 \addplot3+ [only marks] table {plotdata/pgfplotsexample4_grid.dat}; \end{axis} \end{tikzpicture}

If we add the key scatter, the plot mark will also use the colors of the current colormap:

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[ xlabel=$x$, ylabel=$y$, zlabel={$f(x,y) = x\cdot y$}, title=A Scatter Plot Example, ] \addplot3+ [ only marks, scatter, ] table {plotdata/pgfplotsexample4_grid.dat}; \end{axis} \end{tikzpicture}

A more sophisticated example is to draw the approximated function as a surf plot (which requires matrix data) and the underlying grid (which is scattered data) somewhere into the same axis. We choose to place the \((x,y)\) grid points at \(z=1.4\). Furthermore, we want the grid points to be colored according to the value of column f(x) in the input table:

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[ 3d box, zmax=1.4, colormap/viridis, colorbar, xlabel=$x$, ylabel=$y$, zlabel={$f(x,y) = x\cdot y$}, title={Using Coordinate Filters to fix $z=1.4$}, ] % `pgfplotsexample4.dat' contains similar data as in % `pgfplotsexample4_grid.dat', but it uses a uniform % matrix structure (same number of points in every scanline). % See examples above for extracts. \addplot3 [surf,mesh/ordering=y varies] table {plotdata/pgfplotsexample4.dat}; \addplot3 [scatter,scatter src=\thisrow{f(x)},only marks, z filter/.code={\def\pgfmathresult{1.4}}] table {plotdata/pgfplotsexample4_grid.dat}; \end{axis} \end{tikzpicture}

We used z filter to fix the \(z\)-coordinate to \(1.4\). We could also have used the table/z expr=1.4 feature

\addplot3 [scatter,scatter src=\thisrow{f(x)},only marks] table [z expr=1.4] {plotdata/pgfplotsexample4_grid.dat};

to get exactly the same effect. Choose whatever you like best. The z filter works for every coordinate input routine, the z expr feature is only available for \addplot table.

The following example uses mark=cube* and z buffer=sort to place boxes at each input coordinate. The color for each box is determined by point meta={x+y+3}. The remaining keys are just for pretty printing.

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[ view={120}{40}, width=220pt, height=220pt, grid=major, z buffer=sort, xmin=-1,xmax=9, ymin=-1,ymax=9, zmin=-1,zmax=9, enlargelimits=upper, xtick={-1,1,...,19}, ytick={-1,1,...,19}, ztick={-1,1,...,19}, xlabel={$l_1$}, ylabel={$l_2$}, zlabel={$l_3$}, point meta={x+y+z+3}, colormap={summap}{ color=(black) color=(blue) color=(black) color=(white) color=(orange) color=(violet) color=(red) }, scatter/use mapped color={ draw=mapped color,fill=mapped color!70}, ] % `pgfplots_scatter4.dat' contains a large sequence of % the form % l_0 l_1 l_2 % 1 6 -1 % -1 -1 -1 % 0 -1 -1 % -1 0 -1 % -1 -1 0 % 1 -1 -1 % 0 0 -1 % 0 -1 0 \addplot3 [only marks,scatter,mark=cube*,mark size=7] table {plotdata/pgfplots_scatterdata4.dat}; \end{axis} \end{tikzpicture}
4.6.5Mesh Plots
  • /pgfplots/mesh(no value)

Details:

  • A mesh plot uses the same implementation as shader=flat to get one color for each single segment. Thus, if shader=flat mean, the color for a segment is determined using the mean of the color data of adjacent vertices. If shader=flat corner, the color of a segment is the color of the first adjacent vertex.22

  • As soon as mesh is activated, color=mapped color is installed. This is necessary unless one needs a different color – but mapped color is the only color which reflects the color data.

    It is possible to use a different color using the color=(math image)color name(math image) as for any other plot.

  • It is easily possible to add mark=(math image)marker name(math image) to mesh plots, scatter is also possible. Scatter plots will use the same color data as for the mesh.

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[view/az=14] \addplot3 [ mesh, draw=red, samples=10, ] {x^2-y^2}; \end{axis} \end{tikzpicture}

Mesh plots use the mesh legend style to typeset legend images.

  • /pgfplots/mesh/check=false|warning|error (initially error)

  • Allows to configure whether an error is generated if mesh/rows \(\times \) mesh/cols does not equal the total number of coordinates.

    If you know exactly what you are doing, it may be useful to disable the check. If you are unsure, it is best to leave the initial setting.

  • /pgfplots/z buffer=default|none|auto|sort|reverse x seq|reverse y seq|reverse xy seq (initially default)

  • This key allows to choose between different \(z\) buffering strategies. A \(z\) buffer determines which parts of an image should be drawn in front of other parts. Since both, the graphics packages pgf and the final document format .pdf are inherently two dimensional, this work has to be done in . Currently, several (fast) heuristics can be used which work reasonably well for simple mesh and surface plots. Furthermore, there is a (time consuming) sorting method which also works if the fast heuristics fails.

    The \(z\) buffering algorithms of pgfplots apply only to a single \addplot command. Different \addplot commands will be drawn on top of each other, in the order of appearance.

    The choice default checks if we are currently working with a mesh or surface plot and uses auto in this case. If not, it sets z buffer=none.

    The choice none disables \(z\) buffering. This is also the case for two dimensional axes which don’t need \(z\) buffering.

    The choice auto is the initial value for any mesh or surface plot: it uses a very fast heuristics to decide how to execute \(z\) buffering for mesh and surface plots. The idea is to reverse either the sequence of all \(x\)-coordinates, or those of all \(y\)-coordinates, or both. For regular meshes, this suffices to provide \(z\) buffering. In other words: the choice auto will use one of the three reverse strategies reverse * seq (or none at all). The choice auto, applied to patch plots, uses z buffer=sort since patch plots have no matrix structure.

    The choice sort can be used for scatter, line, mesh, surface and patch plots. It sorts according to the depth of each point (or mesh segment). Sorting in uses a slow algorithm and may require a lot of memory (although it has the expected runtime asymptotics \(\mathcal O(N \log N)\)). The depth of a mesh segment is just one number, currently determined as mean over the vertex depths. Since z buffer=sort is actually just a more intelligent way of drawing mesh segments on top of each other, it may still fail. Failure can occur if mesh segments are large and overlap at different parts of the segment (see Wikipedia “Painter’s algorithm”). If you experience problems of this sort, consider reducing the mesh width (the mesh element size) such that they can be sorted independently (for example automatically using patch refines=2, see the patchplots library).

    The remaining choices apply only to mesh/surface plots (i.e. for matrix data) and do nothing more then their name indicates: they reverse the coordinate sequences of the input matrix (using quasi linear runtime). They should only be used in conjunction by z buffer=auto.

22 Starting with pgfplots 1.13 and the associated compatibility level, this holds even in the presence of \(z\) buffering.

4.6.6Surface Plots
  • /pgfplots/surf(no value)

  • /pgfplots/shader=flat|interp|faceted|flat corner|flat mean|faceted interp (initially faceted)

  • Configures the shader used for surface plots. The shader determines how the color data available at each single vertex is used to fill the surface patch.

    The simplest choice is to use one fill color for each segment, the choice flat.

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} \addplot3 [ surf, shader=flat, samples=10, domain=0:1, ] {x^2*y}; \end{axis} \end{tikzpicture}

    There are (currently) two possibilities to determine the single color for every segment:

    • flat corner Uses the color data of one vertex to color the segment. The color of the first vertex determines the color of the entire segment. Note that pgfplots ensures that the outcome is always the same, even if the vertices are reordered due to z buffering or mesh/ordering.

      Note that pgfplots versions up to and including 1.12 chose one of them without respectiving reordering. In order to have the ordering independent of other features, you have to write compat=1.13 or newer.

    • flat mean Uses the mean of all four color data values as segment color. This is the initial value as it provides symmetric colors for symmetric functions.

    The choice flat is actually the same as flat mean. Please note that shader=flat mean and shader=flat corner also influence mesh plots – the choices determine the mesh segment color.

    Another choice is shader=interp which uses Goraud shading (smooth linear interpolation of two triangles approximating rectangles) to fill the segments.

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} \addplot3 [ surf, shader=interp, samples=10, domain=0:1, ] {x^2*y}; \end{axis} \end{tikzpicture}

    The shader=interp employs a low-level shading implementation which is currently available for the following drivers:

    • the postscript driver \def\pgfsysdriver{pgfsys-dvips.def},

    • the pdflatex driver \def\pgfsysdriver{pgfsys-pdftex.def},

    • the lualatex driver \def\pgfsysdriver{pgfsys-pdftex.def} and
      \def\pgfsysdriver{pgfsys-luatex.def},

    • the dvipdfmx driver \def\pgfsysdriver{pgfsys-dvipdfmx.def}.

    For other drivers, the choice shader=interp will result in a warning and is equivalent to shader=flat mean. See also below for detail remarks.

    Note that shader=interp,patch type=bilinear allows real bilinear interpolation, see the patchplots library.

    The choice shader=faceted uses a constant fill color for every mesh segment (as for flat) and the value of the key /pgfplots/faceted color to draw the connecting mesh elements:

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} \addplot3 [ surf, shader=faceted, samples=10, domain=0:1, ] {x^2*y}; \end{axis} \end{tikzpicture}

    The last choice is shader=faceted interp. As the name suggests, it is a mixture of interp and faceted in the sense that each element is shaded using linear triangle interpolation (see also the patchplots library for bilinear interpolation) in the same way as for interp, but additionally, the edges are colored in faceted color:

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} \addplot3 [ surf, shader=faceted interp, samples=10, domain=0:1, ] {x^2*y}; \end{axis} \end{tikzpicture}

    In principle, there is nothing wrong with the idea as such, and it looks quite good – but it enlarges the resulting PDF document considerably and might take a long time to render. It works as follows: for every mesh element (either triangle for patch plots or rectangle for lattice plots), it creates a low level shading. It then fills the single mesh element with that shading, and strokes the edges with faceted color. The declaration of that many low level shadings is rather inefficient in terms of PDF objects (large output files) and might render slowly.23 For orthogonal plots (like view={0}{90}), the effect of faceted interp can be gained with less cost if one uses two separate \addplot commands: one with surf and one with mesh. Handle this choice with care.

Details:

  • All shaders support z buffer=sort (starting with version 1.4).

  • The choice shader=faceted is the same as shader=flat – except that it uses a special draw color.

    So, shader=faceted has the same effect as

    shader=flat,draw=\pgfkeysvalueof{/pgfplots/faceted color}.

  • The flat shader uses the current draw and fill colors. They are set with color=mapped color and can be overruled with draw=(math image)draw color(math image) and fill=(math image)fill color(math image). The mapped color always contains the color of the color map.

  • You easily add mark=(math image)plot mark(math image) to mesh and/or surface plots or even colored plot marks with scatter. The scatter plot feature will use the same color data as for the surface.

    But: Markers and surfaces do not share the same depth information. They are drawn on top of each other.

  • Remarks on shader=interp:

    • It uses the current color map in any case, ignoring draw and fill.

    • For surface plots with lots of points, shader=interp produces smaller pdf documents, requires less compilation time in and requires less time to display in Acrobat Reader than shader=flat.

    • The postscript driver truncates coordinates to 24 bit – which might result in a loss of precision (the truncation is not very intelligent). See the surf shading/precision key for details. To improve compatibility, this 24 bit truncation algorithm is enabled by default also for PDF documents.

    • The choice shader=interp works well with either Acrobat Reader or recent versions of free viewers.24 However, some free viewers show colors incorrectly (like evince). I hope this message will soon become outdated… if not, provide bug reports to the Linux community to communicate the need to improve support for Type 4 (patch) and Type 5 PDF (surf) and Type 7 (patch and elements of the patchplots library) shadings.

    • The interp shader yields the same outcome as faceted interp,faceted color=none, although faceted interp requires much more resources.

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[colormap/viridis] \addplot3 [ surf, shader=flat, draw=black, samples=10, domain=0:1, ] {x^2*y}; \end{axis} \end{tikzpicture}

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[colormap/viridis] \addplot3 [ surf, shader=faceted, scatter,mark=*, samples=10, domain=0:1, ] {x^2*y}; \end{axis} \end{tikzpicture}

Note that the shader always interacts with colormap access. In particular, colormap access=piecewise constant combined with shader=interp results in a filled contour plot, see Section 4.6.9 for details.

  • /pgfplots/faceted color={(math image)color name(math image)} (initially mapped color!80!black)

  • Defines the color to be used for meshes of faceted surface plots.

    Set faceted color=none to disable edge colors.

Call for volunteers:

it would be nice if the fine-tuning of these keys would be unnecessary. If someone has well-founded suggestions (like knowledge and perhaps exhaustive experiments) on how to improve the feature, let me know.

Note that mesh/interior colormap cannot be combined with mesh/refines currently.

Note that mesh/interior colormap will increase compilation times due to the computation of normal vectors.

  • /pgfplots/mesh/interior colormap thresh={(math image)Number between \(-1.0\) and \(+1.0\)(math image)} (initially 0)

  • A threshold which moves the boundary between the colormap and interior colormap in favor of colormap (if the value is negative) or in favor of interior colormap (if the value is positive).

    The extreme value \(-1\) essentially deactivates interior colormap whereas the other extreme \(+1\) deactivates colormap.

    See above for an example.

  • /pgfplots/surf shading/precision=pdf|postscript|ps (initially postscript)

  • A key to configure how the low level driver for shader=interp writes its data. The choice pdf uses 32 bit binary coordinates (which is lossless). The resulting .pdf files appear to be correct, but they can’t be converted to postscript – the converter software always complains about an error.

    The choice postscript (or, in short, ps) uses 24 bit truncated binary coordinates. This results in both, readable .ps and .pdf files. However, the truncation is lossy.

    If anyone has ideas how to fix this problem: let me know. As far as I know, Postscript should accept 32 bit coordinates, so it might be a mistake in the shading driver.

23 My experience is as follows: Acrobat reader can efficiently render huge interp shadings. But it is very slow for faceted interp shadings. Linux viewers like xpdf are reasonably efficient for interp (at least with my bugfixes to libpoppler) and are also fast for faceted interp shadings.

24 The author of this package has submitted bugfixes to xpdf/libpoppler which should be part of the current stable versions of many viewers.

25 This may change in future versions.

4.6.7Surface Plots with Explicit Color

The surface plots described in Section 4.6.6 are all based on colormaps. This section introduces a different type of surface plot. In fact, it uses the very same plot handlers: it applies to mesh, surf, and patch plots. However, the way colors are provided and the way pgfplots interpolates colors is substantially different.

This section describes surface plots with explicit colors. These expect colors like red, green, or rgb=(0.5,0.2,1) for every vertex of the mesh – and interpolates smoothly between these vertices. This appears to be simpler, perhaps even more straightforward than surface plots based on colormaps. It is not. Surface plots with explicit color are more difficult to define, and they are more difficult to read.

If you are in doubt of whether to use a surface colored by a colormap or explicit colors, you should prefer colormaps for reasons discussed below.

  • /pgfplots/mesh/color input=colormap|explicit|explicit mathparse (initially colormap)

  • Allows to configure how pgfplots expects color input for surface plots.

    The choice colormap uses the standard colormaps. This particular choice expects scalar values of point meta which are mapped linearly into the colormap. It resembles the surface plots which are explained in more detail in Section 4.6.6. It is the default configuration and covers (probably) most common use cases.

    The choice explicit expects explicitly provided point meta of symbolic form: every coordinate of your input coordinate stream is supposed to have an explicitly defined color as point meta. Here, “explicitly provided” refers to point meta=explicit symbolic. This choice and the available color formats are explained in all detail in the following subsections.

    The choice explicit mathparse is similar to explicit, but it allows to provide just one math expression which is evaluated for every coordinate. The math expression can be of the form rgb=x,y,0.5 in which case x is used to define the “red” component, y is used to define the “green” component and the “blue” component is fixed to 0.5. This key is also explained in more detail in the following subsections.

The main use case of mesh/color input=colormap is to allow a map between the interpolated colors and some value of interest. This map can be shown as colorbar:

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} % \usepgfplotslibrary{patchplots} \begin{tikzpicture} \begin{axis}[small,view={0}{90},colorbar] \addplot3 [ surf, shader=interp, patch type=bilinear, ] coordinates { (0,0,0) (1,0,0) (0,1,0) (1,1,1) }; \end{axis} \end{tikzpicture}

Note that the preceding example is a standard surf plot except for patch type=bilinear which controls how color is to be interpolated. There is a \(2 \times 2\) matrix, and its \(z\) values are used as color data. Clearly, value \(z=0\) corresponds to blue and \(z=1\) corresponds to red – and all other colors in-between are not directly related to blue and red; they are taken from the colormap. The colormap defines which colors appear: those which make up the colormap and those which can occur as interpolated colors between the colors of the color map. The pairwise mixture of colors is a property of mesh/color input=colormap, not of mesh/color input=explicit (where more than two colors are mixed together). Furthermore, the surface indicates contours of constant \(z\) level. Take, for example, the yellow contour. We know that it has some value between \(0.3\) and \(0.4\), say \(0.35\). Since these shadings are continuous, we know that the point \(z=0.35\) occurs between \(z=0\) and \(z=1\) – at every point of the surface. Due to the colormap, each point on the surface which has \(z=0.35\) will receive the yellow color. This is because the interpolation is carried out on the scalar point meta value, which is afterwards mapped into the colormap. This contour property is also unique for colormap surfaces.

The other two choices are explained in all detail in the next subsections.

4.6.7.1Providing Colors Explicitly For Each Coordinate

Here is a simple approach with the same vertices as the colormap example above, but with explicit colors:

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} % \usepgfplotslibrary{patchplots} \begin{tikzpicture} \begin{axis}[small,view={0}{90}] \addplot3 [ surf, shader=interp, patch type=bilinear, mesh/color input=explicit, ] coordinates { (0,0,0) [color=blue] (1,0,0) [color=green] (0,1,0) [color=yellow] (1,1,1) [color=red] }; \end{axis} \end{tikzpicture}

The coordinates and the view is the same, even the way colors are being interpolated bilinearly. However, we have four different colors in the corners. We see these corners in the output, and we see that they are smoothly mixed together. However, the mix contains all four colors, not just two. As a direct consequence, there are no contour lines.

The absence of direct information how to map color information to “some information of the data visualization” implies that if you want to use surface plots with explicit color, you have to state clearly what you want to show. This is considerably simpler for colormaps.

The following example configures \(z=0\) to receive blue and \(z=1\) to receive red as in our preceding colormap example (see above) using mesh/color input=explicit.

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} % \usepgfplotslibrary{patchplots} \begin{tikzpicture} \begin{axis}[small,view={0}{90}] \addplot3 [ surf, shader=interp, patch type=bilinear, mesh/color input=explicit, ] coordinates { (0,0,0) [color=blue] (1,0,0) [color=blue] (0,1,0) [color=blue] (1,1,1) [color=red] }; \end{axis} \end{tikzpicture}

We see the bilinear nature of the interpolation; it is related to that of mesh/color input=colormap above (compare the contour lines in-between). In most cases, you simply want to show some contour lines. And for such cases, a colormap is the way to go.

There might be cases where mesh/color input=explicit is adequate. However, you will need to think it through properly. And you need to explain clearly what you did because your audience will also have to think a lot before they make sense of any data visualization based on explicit color interpolation.

The choice mesh/color input=explicit expects a choice of point meta which results in symbolic values. In this context, “symbolic” refers to a special color definition:

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[minor x tick num=1] \addplot [ patch, shader=interp, mesh/color input=explicit, ] table [meta=c] { x y c 0 0 color=green % default color model is rgb: 1 1 1,0,0 2 0 1,1,0 1.5 1 cmyk=1,0,0,0 2.5 0 gray=0.5 3.5 1 color=red!80!black 3 0 1,0,1 4 1 0,0,1 5 0 rgb255=0,128,128 }; \end{axis} \end{tikzpicture}

The previous example defines a patch plot with three triangle patches, each made up of three vertices which are placed as is into the input coordinate stream. Each vertex has its color data in column c. The format of color specifications is explained in more detail in the following paragraph.

As soon as you write mesh/color input=explicit, pgfplots checks the current value of point meta. If the current value of point meta is none, it is set to point meta=explicit symbolic (that is what happened in our example above). If the current value of point meta is some choice which yields numeric output (like point meta=x or point meta=\thisrow{x}+1), it is set to point meta=explicit symbolic. If the current value of point meta is already of symbolic form, it is left unchanged.

Consequently, our example above sets point meta=explicit symbolic as soon as it encounters mesh/color input=explicit. The explicit symbolic input handler in turn expects the coordinate stream to provide point meta data for every streamed coordinate. We use a table here, and a table reads its color data from the column name provided in the table/meta key.

The accepted format of colors is quite similar to that of colormap definitions (compare Section 4.7.6.1). The common format is (math image)color model(math image)=(math image)arguments(math image). In contrast to the similar input format inside of colormap definitions, the syntax here has no round braces and does not have the (math image)length(math image) argument. Nevertheless, the same (math image)color model(math image)s with the same (math image)arguments(math image) are accepted. The choices are

rgb

=(math image)red(math image),(math image)green(math image),(math image)blue(math image) where each component is in the interval \([0,1]\),

rgb255

=(math image)red(math image),(math image)green(math image),(math image)blue(math image) is similar to rgb except that each component is expected in the interval [0,255],

gray

=(math image)value(math image) with (math image)value(math image) in the interval \([0,1]\),

color

=(math image)named color(math image) where (math image)named color(math image) is a predefined (named) color like ‘red’ or a color expression like ‘red!50’,

cmyk

=(math image)cyan(math image),(math image)magenta(math image),(math image)yellow(math image),(math image)black(math image) where each component is in the interval \([0,1]\),

cmyk255

=(math image)cyan(math image),(math image)magenta(math image),(math image)yellow(math image),(math image)black(math image) is the same as cmyk but expects components in the interval \([0,255]\),

cmy

=(math image)cyan(math image),(math image)magenta(math image),(math image)yellow(math image) where each component is in the interval \([0,1]\),

hsb

=(math image)hue(math image),(math image)saturation(math image),(math image)brightness(math image) where each component is in the interval \([0,1]\),

Hsb

=(math image)hue(math image),(math image)saturation(math image),(math image)brightness(math image) is the same as hsb except that (math image)hue(math image) is accepted in the interval \([0,360]\) (degree),

HTML

=(math image)hex red(math image)(math image)hex green(math image)(math image)hex blue(math image) where component is expected to be a hex number between 00 and FF (a variant of rgb255),

wave

=(math image)wave length(math image) which expects a single wave length as numeric argument in the range \([363,814]\).

  • /pgfplots/mesh/colorspace explicit color input=rgb|rgb255|cmy|cmyk|cmyk255|gray|wave|hsb
    |Hsb|HTML
    (initially rgb)

  • If the input color has no color model, the color components are interpreted as color in the color model specified as argument to this key.

    This key has just one purpose: to omit the (math image)color model(math image) if it is the same for lots of points anyway.

26 Colorspace transformations are unavailable for plain and Cont. For these cases, you have to ensure that input and output color model are the same.

4.6.7.2Providing Color Components as Table

The previous section shows how to provide a single symbolic color expression for each coordinate, namely using point meta=explicit symbolic.

Another use case might be to provide a table containing both the coordinate values and one column by color component. In order to assemble the color specification from the input table, you can provide a symbolic expression:

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} \addplot [ patch, shader=interp, mesh/color input=explicit, point meta={symbolic= {\thisrow{R},\thisrow{G},\thisrow{B}} }, ] table { x y R G B 0 0 0 1 0 1 1 1 0 0 2 0 0 0 1 }; \end{axis} \end{tikzpicture}

The preceding example employs a patch plot with triangular elements as we have seen before. Furthermore, it uses explicit color input – but combined with point meta={symbolic={(math image)value(math image)}} (note the extra pair of braces). This choice accepts arbitrary symbols on input which will be reevaluated (expanded) for every coordinate. In our example, we simply read the values from table columns using \thisrow. Since the default input colorspace is RGB, this results in the expected triangle with red, green, and blue corners. The result has to form a valid color specification.

Note that the symbolic expression is purely string based in this context. If you plan to use math expressions, you have to use mesh/color input=explicit mathparse as explained in the following section.

4.6.7.3Providing Colors as Math Expression

The key mesh/color input has two choices for explicit color input. The choice explicit has been discussed in the preceding paragraphs, it expects one color specification for every node for which colors are needed. It also accepts a kind of string based expressions to concatenate the expected color specification in a suitable way.

The second choice mesh/color input=explicit mathparse is almost the same – with one major difference: it allows to provide math expressions inside of the point meta value. However, the provided math expressions need to form a color specification which typically has more than one color component.

With this choice, the value of point meta is of symbolic form, but the color components are reevaluated with the math parser for every input point which has color data. The most convenient way to provide such expressions is point meta={symbolic={(math image)R(math image),(math image)G(math image),(math image)B(math image)}} (again, note the extra set of braces for the argument).

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} \addplot [ surf, shader=interp, mesh/color input=explicit mathparse, point meta={symbolic={x,\thisrow{y},0}}, ] table { x y 0 0 1 0 0 1 1 1 }; \end{axis} \end{tikzpicture}

The preceding example is a surface plot with a \(2 \times 2\) input matrix. Note that the table has no explicit point meta data. The point meta data is acquired from a common math expression which uses the final \(x\) coordinate as (math image)red(math image) component, the value seen in the current row and column y as (math image)green(math image) value and constant value (math image)blue(math image)\(=0\). Consequently, the output is black in the lower left corner since black is \((0,0,0)\), red in the lower right corner, green in the upper left corner, and a mixture of both along the diagonal.

The value provided as point meta={symbolic={(math image)value(math image)}} is of the same form as for mesh/color input=explicit, i.e. it is supposed to be of the form (math image)color model(math image)=(math image)color components(math image). If the (math image)color model(math image) is omitted, it defaults to mesh/colorspace explicit color input (which is rgb by default).

Since the math expression can be anything, it can safely be combined with plot by expression.

A potential use case could be to show a surface with \((x,y,z)\) and some two-dimensional quantity which is encoded as mixture of red and green. The following example relies on mesh/color input=explicit mathparse and point meta=symbolic to provide a vector of math expressions:

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} % \usepgfplotslibrary{patchplots} \begin{tikzpicture} \begin{axis} % this example burns colors if opacity % is active in the document. \addplot3 [ patch, patch type=bilinear, mesh/color input=explicit mathparse, domain=0:1, samples=30, point meta={ symbolic={ (sin(deg(x*pi*2))+1)/2, % R (sin(deg(y*pi*2))+1)/2, % G 0 % B } }, ] {sin(deg(x*pi*2))+sin(deg(y*pi*2))}; \end{axis} \end{tikzpicture}

Note that the preceding example suffers from color burning:27 the green areas become too bright and the black areas become too dark. Note that the picture is entirely acceptable if it is written as stand-alone picture. But as soon as you import the picture (either as .pdf or as .png) into a document for which opacity is active, it suffers from burned colors.

The color burning is caused by the combination of RGB colorspace, the special color set in this example, and the color blending which is activated by opacity. Note that it is enough to activate opacity somewhere in the document.

In order to repair the problem for the picture at hand, one has to choose a different output colorspace:

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} % \usepgfplotslibrary{patchplots} \begin{tikzpicture} \begin{axis} \addplot3 [ patch, patch type=bilinear, mesh/color input=explicit mathparse, % % CMYK produces better quality here % since the manual has opacity enabled mesh/colorspace explicit color output=cmyk, domain=0:1, samples=30, point meta={ symbolic={ (sin(deg(x*pi*2))+1)/2, % R (sin(deg(y*pi*2))+1)/2, % G 0 % B } }, ] {sin(deg(x*pi*2))+sin(deg(y*pi*2))}; \end{axis} \end{tikzpicture}

The key mesh/colorspace explicit color output transforms every input RGB color to a matching CMYK color. This, in turn, is a lossy transformation which seems to lack a trivial solution.28

Math expressions can also be used for complicated input color spaces, for example the wave colorspace.

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} \addplot3 [ surf, shader=interp, mesh/color input=explicit mathparse, domain=0:1, samples y=2, point meta={symbolic={wave=363+x*(814-363)}}, ] {x*y}; \end{axis} \end{tikzpicture}

Note that you have to take care that the color components are within the expected bounds.

27 At least in Acrobat Reader.

28 If some expert in color space operations can contribute best practices here, feel free to contact me.

4.6.8Contour Plots

pgfplots supports visualization of contour plots. Due to the complexity of these algorithms, pgfplots needs more computation power. You have the choice between contour lua which requires no additional software to be installed, but requires you to invoke lualatex instead of pdflatex, or you can resort to contour gnuplot in which case you need to allow to invoke gnuplot and you need to install gnuplot.

Both contour lua and contour gnuplot expect matrix input in the same format as for mesh or surf (that includes any of the pgfplots matrix input methods). At the time of this writing, both require temporary files for input and output data. The resulting contour lines are visualized with the contour prepared plot handler which takes precomputed contour line coordinates and handles their visualization (contour/draw color, contour/labels etc.). In short: both plot handlers expect the usual matrix input and generate contour lines. The recommended way to visualize contour lines is contour lua since it requires no 3rd party programs, but requires you to invoke lualatex.

We discuss the high level interface to external programs first and continue with contour prepared later-on.

  • /pgfplots/contour lua={(math image)options with ‘contour/’ or ‘contour external/’ prefix(math image)}

  • \addplot+[ contour lua={(math image)options with ‘contour/’ or ‘contour external/’ prefix(math image)}]

  • This algorithm was implemented and contributed by Francesco Poli

    This is a high level contour plot interface. It expects matrix data in the same way as two dimensional surf or mesh plots do. It then computes contours and visualizes them.

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[view={0}{90}] \addplot3 [ contour lua ] {x*y}; \end{axis} \end{tikzpicture}

    The example uses \addplot3 together with expression plotting, that means the input data is of the form \((x_i,y_i,f(x_i,y_i))\). The view={0}{90} flag means “view from top”, otherwise the contour lines would have been drawn as \(z\) value:

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} \addplot3 [ contour lua ] {exp(0-x^2-y^2)}; \end{axis} \end{tikzpicture}

    As mentioned, you can use any of the pgfplots input methods as long as it yields matrix output. Thus, we can reuse our introductory example of matrix data, this time with inline data:

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[view={0}{90}] \addplot3 [ contour lua ] coordinates { (0,0,0) (1,0,0) (2,0,0) (3,0,0) (0,1,0) (1,1,0.6) (2,1,0.7) (3,1,0.5) (0,2,0) (1,2,0.7) (2,2,0.8) (3,2,0.5) }; \end{axis} \end{tikzpicture}

    What happens behind the scenes is that pgfplots takes the input matrix and writes all encountered coordinates to a temporary file, including the end-of-scanline markers. Then, it generates a small lua script and invokes a lua algorithm to compute the contour coordinates, writing everything into a temporary output file. Afterwards, it includes lua’s output file just as if you’d write \addplot3[contour prepared] file {(math image)temporaryfile(math image)};.

    All this invocation of lua, including input/output file management is transparent to the user. It only requires two things: first of all, it requires matrix data as input.29

    The contouring algorithm of contour lua accepts \((x,y,z)\) and, in addition the point meta. Its contour information is always based on point meta. Usually, point meta and \(z\) are the same. But it is also possible to use a different point meta:

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[ xlabel={$x$}, ylabel={$y$}, zlabel={$z$}, view/h=70, view/v=50, ] % z= -x+y \addplot3[surf,samples=2,shader=interp] table { x y z -5 -5 0 5 -5 -10 -5 5 10 5 5 0 }; % same data, but with contour % and color data v= x+y : \addplot3[ contour lua={number=3}, point meta=\thisrow{v}, ] table { x y z v -5 -5 0 -10 5 -5 -10 0 -5 5 10 0 5 5 0 10 }; \end{axis} \end{tikzpicture}

    The resulting data can be projected onto a separate slice, for example using z filter.

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} \addplot3 [ surf, shader=interp ] coordinates { (0,0,0) (1,0,0) (2,0,0) (3,0,0) (0,1,0) (1,1,0.6) (2,1,0.7) (3,1,0.5) (0,2,0) (1,2,0.7) (2,2,0.8) (3,2,0.5) }; \addplot3 [ contour lua, z filter/.code={\def\pgfmathresult{1}}, ] coordinates { (0,0,0) (1,0,0) (2,0,0) (3,0,0) (0,1,0) (1,1,0.6) (2,1,0.7) (3,1,0.5) (0,2,0) (1,2,0.7) (2,2,0.8) (3,2,0.5) }; \end{axis} \end{tikzpicture}

    There are several fine-tuning parameters of the input/output file management, and it is even possible to invoke different programs than lua (see contour gnuplot). These details are discussed at the end of this section.

  • /pgfplots/contour/contour dir=x|y|z (initially z)

Note: The key contour dir was introduced in order to support external contouring algorithms which operate on three coordinates (like contour gnuplot). However, contour lua operates on \((x,y,z)\) and point meta and can achieve the same effect using point meta=x! Thus, this key has become of less importance since contour lua.

This key allows to generate contours with respect to another direction.

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[ title={$x \exp(-x^2-y^2)$}, domain=-2:2, ] \addplot3 [ contour lua={ contour dir=x, labels=false, number=15, }, thick, ] {exp(-x^2-y^2)*x}; \end{axis} \end{tikzpicture}

The input data is the same as before – it has to be given in matrix form. The key contour dir configures the algorithm to compute contours along the provided direction.

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[ title={$x \exp(-x^2-y^2)$}, domain=-2:2, ] \addplot3 [ contour lua={ contour dir=y, labels=false, number=15, }, thick, ] {exp(-x^2-y^2)*x}; \end{axis} \end{tikzpicture}

This function is also available for parameterized surfaces.

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[view={60}{30},axis equal image] \addplot3 [ contour lua={ contour dir=x, number=20, labels=false, }, samples=30,domain=-1:1,y domain=0:2*pi, ] ( {sqrt(1-x^2) * cos(deg(y))}, {sqrt( 1-x^2 ) * sin(deg(y))}, x ); \end{axis} \end{tikzpicture}

Note, however, that each contour line receives a single color. This is what one expects for a contour plot: it has a single style, and a single contour level. Note furthermore that the color which is assigned to a contour plot with contour dir=x is different compared with the color assigned to a contour plot with contour dir=z: the argument of contour dir implicitly defines the argument for point meta (also known as color data). More precisely, a contour plot with contour dir=x has point meta=x whereas a contour plot with contour dir=z uses point meta=z.

If you would like to have individually colored segments inside of contours, you have to use a different plot handler. There is a simple alternative which works well in many cases: you can use a standard mesh plot combined with patch type=line:

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[ title={$x \exp(-x^2-y^2)$}, domain=-2:2, xlabel=$x$, ylabel=$y$, ] \addplot3 [ samples y=10, samples=25, mesh, patch type=line, thick, ] {exp(-x^2-y^2)*x}; \end{axis} \end{tikzpicture}

Here, we did not generate a contour plot. We generated a mesh plot with patch type=line. The choice patch type=line causes an inherently one-dimensional plot as opposed to the default matrix style visualization which would be generated by mesh in different cases. Since a mesh plot uses one color for every patch segment, we have a lot of freedom to color the segments. In the example above, we have the default configuration point meta=z, i.e. the \(z\) value defines the color.

The fact that a mesh plot with patch type=line yields almost the same output as contour dir=y is an artifact of the scanline encoding. Our example uses \addplot3 expression which relies on mesh/ordering=x varies. If we visualize the resulting matrix by means of patch type=line, the visualization follows the scanlines which vary along the \(x\)-axis. In our example, we used samples y=10 to control the number of “contour lines”.

A consequence of the previous paragraph is that we have a more challenging task at hand if we want to get the same effect as contour dir=x: we would need mesh/ordering=y varies. In our case, we would need to transpose the data matrix. For \addplot3 expression, this is relatively simple: we can exchange the meaning of x and y to get a transposition:

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[ title={$x \exp(-x^2-y^2)$}, domain=-2:2, xlabel=$x$, ylabel=$y$, ] \addplot3 [ samples y=10, samples=25, mesh, patch type=line, thick, ] (y,x,{exp(-x^2-y^2)*y}); \end{axis} \end{tikzpicture}

This is the same example as above – but as you noted, the meaning of x and y in the expression has been exchanged and the notation has been switched to a parametric plot. Such an approach is also possible for data files, but pgfplots cannot transpose the matrix ordering on its own.

Coming back to contour dir, we can also use its output to generate several contour projections using coordinate filters.

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[ xlabel=$x$,ylabel=$y$, enlargelimits=false, 3d box=complete, ] \addplot3 [surf] {x^2-y^2}; \addplot3 [ contour lua={contour dir=y, draw color=red,labels=false}, y filter/.expression={-5}, ] {x^2-y^2}; \addplot3 [ contour lua={contour dir=x, draw color=blue,labels=false}, x filter/.expression={5}, ] {x^2-y^2}; \addplot3 [ contour lua={contour dir=z, draw color=black,labels=false}, z filter/.expression={25}, ] {x^2-y^2}; \end{axis} \end{tikzpicture}

The preceding example uses a fixed draw color combined with x filter, y filter, and z filter to fix the contours in one of the axis planes.

Technical background:

This section is probably unnecessary and can be skipped. The key contour dir is implemented by means of coordinate permutations. Since contouring algorithms always support contour dir=z, it is relatively simple to compute \(z\)–contour lines from input matrixes \(X, Y, Z\). The choice contour dir=z key simply takes the input as is. The choice contour dir=x reorders the input coordinates to yzx. The choice contour dir=y reorders the input coordinates to xzy. All this reordering is applied before coordinates are handed over to the contouring algorithm (see contour external) and is undone when reading the results back from the contouring algorithm. That means that contour dir is also available for contour prepared. In this context, contour prepared is supposed to be the output of some contouring algorithm. Its input coordinates are automatically reordered according to the inverse permutation. This allows to draw \(x\) or \(y\) contours which are given in the prepared format.

  • /pgfplots/contour gnuplot={(math image)options with ‘contour/’ or ‘contour external/’ prefix(math image)}

  • \addplot+[ contour gnuplot={(math image)options with ‘contour/’ or ‘contour external/’ prefix(math image)}]

  • This is a high level contour plot interface. It expects matrix data in the same way as two dimensional surf or mesh plots do. It then computes contours and visualizes them. The handler contour gnuplot works in the very same way as contour lua and produces results of comparable quality. All the keys and examples mentioned above apply for contour gnuplot as well. However, you necessarily need to apply the following steps before you can use contour gnuplot:

    • 1. install gnuplot on your system.

    • 2. Ensure that you can invoke gnuplot from a terminal (like cmd.exe or bash). To this end, you will need to add gnuplot to the PATH environment variable.

    • 3. When invoking pdflatex, you need to enable system calls.

      For Live, this is pdflatex -shell-escape. For MiK, the system uses pdflatex -enable-write18 . Some distributions require you to use two slashes for the option.

    See also the documentation for plot gnuplot for a related section.

    The usage is the same as for contour lua, so please refer to the contour lua and its examples.

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[view={0}{90}] \addplot3 [ contour gnuplot ] {x*y}; \end{axis} \end{tikzpicture}

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[view={0}{90}] \addplot3 [ contour gnuplot={number=6} ] {exp(-x^2-y^2)}; \end{axis} \end{tikzpicture}
  • /pgfplots/contour prepared={(math image)options with ‘contour/’ prefix(math image)}

  • \addplot+[contour prepared={(math image)options with ‘contour/’ prefix(math image)}]

  • A plot handler which expects already computed contours on input and visualizes them. It cannot compute contours on its own.

    • /pgfplots/contour prepared format=standard|matlab (initially standard)

    • There are two accepted input formats. The first is a long sequence of coordinates of the form \((x,y,z)\) where all successive coordinates with the same \(z\) value make up a contour level (this is only part of complete truth, see below). The end-of-scanline markers (empty lines in the input) mark an interruption in one contour level.

      For example, contour prepared format=standard could be30

      (-tikz- diagram)

      % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} \addplot [contour prepared] table { 2 2 0.8 0.857143 2 0.6 1 1 0.6 2 0.857143 0.6 2.5 1 0.6 2.66667 2 0.6 0.571429 2 0.4 0.666667 1 0.4 1 0.666667 0.4 2 0.571429 0.4 3 0.8 0.4 0.285714 2 0.2 0.333333 1 0.2 1 0.333333 0.2 2 0.285714 0.2 3 0.4 0.2 }; \end{axis} \end{tikzpicture}

      Note that the empty lines are not necessary in this case: empty lines make only a difference if they occur within the same contour level (i.e. if the same \(z\) value appears above and below of them).

      The choice contour prepared format=matlab expects two-dimensional input data where the contour level and the number of elements of the contour line are provided as \(x\)- and \(y\)-coordinates, respectively, of a leading point. Such a format is used by matlab’s contour algorithms, i.e. it resembles the output of the Matlab commands data=contour(...) or data=contourc(...).

      (-tikz- diagram)

      % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} \addplot [ contour prepared, contour prepared format=matlab, ] table { % (0.2,5) ==> contour `0.2' (x), 5 points follow (y): 2.0000000e-01 5.0000000e+00 3.0000000e+00 4.0000000e-01 2.0000000e+00 2.8571429e-01 1.0000000e+00 3.3333333e-01 3.3333333e-01 1.0000000e+00 2.8571429e-01 2.0000000e+00 % (0.4,5) ==> contour `0.4', consists of 5 points 4.0000000e-01 5.0000000e+00 3.0000000e+00 8.0000000e-01 2.0000000e+00 5.7142857e-01 1.0000000e+00 6.6666667e-01 6.6666667e-01 1.0000000e+00 5.7142857e-01 2.0000000e+00 % (0.6,6) ==> contour `0.6', has 6 points 6.0000000e-01 6.0000000e+00 2.6666667e+00 2.0000000e+00 2.5000000e+00 1.0000000e+00 2.0000000e+00 8.5714286e-01 1.0000000e+00 1.0000000e+00 1.0000000e+00 1.0000000e+00 8.5714286e-01 2.0000000e+00 }; \end{axis} \end{tikzpicture}

      In case you use Matlab, you can generate such data with

      [x,y]=meshgrid(linspace(0,1,15));
      data=contour(x,y,x.*y);
      data=data';
      save 'exporteddata.dat' data -ASCII
      

    As already mentioned in the beginning, the \(z\)-coordinate is not necessarily the coordinate used to delimit contour levels. In fact, the point meta data is acquired here, i.e. you are free to use whatever \(z\) coordinate you want as long as you have a correct point meta value. The example from above could be modified as follows:

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[ title=Separating $z$ from Color Value, xlabel=$x$, ylabel=$y$, ] \addplot3 [ contour prepared, point meta=\thisrow{level}, ] table { x y z level 0.857143 2 0.4 0.6 1 1 0.6 0.6 2 0.857143 0.6 0.6 2.5 1 0.6 0.6 2.66667 2 0.4 0.6 0.571429 2 0.2 0.4 0.666667 1 0.4 0.4 1 0.666667 0.4 0.4 2 0.571429 0.4 0.4 3 0.8 0.2 0.4 0.285714 2 0 0.2 0.333333 1 0.2 0.2 1 0.333333 0.2 0.2 2 0.285714 0.2 0.2 3 0.4 0 0.2 }; \end{axis} \end{tikzpicture}

    The example above uses different \(z\)-coordinates for each first and each last point on contour lines. The contour lines as such are defined by the level column since we wrote point meta=\thisrow{level}. Such a feature also allows contour prepared for nonstandard axes, compare the examples for the ternary lib at 1318.

    • /pgfplots/contour/draw color={(math image)color(math image)} (initially mapped color)

    • Defines the draw color for every contour. Note that only mapped color actually depends on the contour level.

    • /pgfplots/contour/labels={(math image)true,false(math image)} (initially true)

    • Configures whether contour labels shall be drawn or not.

    • /pgfplots/contour/label distance={(math image)dimension(math image)} (initially 70pt)

    • Configures the distance between adjacent contour labels within the same contour level.

  • /pgfplots/contour external={(math image)options with ‘contour/’ or ‘contour external/’ prefix(math image)}

  • \addplot+[ contour external={(math image)options with ‘contour/’ or ‘contour external/’ prefix(math image)}]

  • This handler constitutes a generic interface to external programs to compute contour lines. The contour gnuplot method is actually a special case of contour external. At the time of this writing, even contour lua is a special case of contour external.

    • /pgfplots/contour external/file={(math image)base file name(math image)} (initially empty)

    • The initial configuration is to automatically generate a unique file name.

    • /pgfplots/contour external/scanline marks=false|if in input|required|true (initially if in input)

    • Controls how contour external writes end-of-scanline markers.

      The choice false writes no such markers at all. In this case, script should contain mesh/rows and/or mesh/cols.

      The choice if in input generates end-of-scanline markers if they appear in the provided input data (either as empty lines or if the user provided at least two of the three options mesh/rows, mesh/cols, or mesh/num points explicitly).

      The choice required works like if in input, but it will fail unless there really was such a marker.

      The choice true is an alias for required.

    • /pgfplots/contour external/script={(math image)code for external program(math image)} (initially empty)

    • Provides template code to generate a script for the external program. Inside of (math image)code for external program(math image), the placeholder \infile will expand to the temporary input file and \outfile to the temporary output file. The temporary \infile is a text file containing one point on each line, in the specified by script input format, separated by tabstops. Whenever a scanline is complete, an empty line is issued (but only if these scanline markers are found in the input stream as well). The complete set of scanlines forms a matrix. There are no additional comments or extra characters in the file. The macro \ordering will expand to 0 if the matrix is stored in mesh/ordering=x varies and \ordering will be 1 for mesh/ordering=y varies.

      Inside of (math image)code for external program(math image), you can also use \pgfkeysvalueof{/pgfplots/mesh/rows} and \pgfkeysvalueof{/pgfplots/mesh/cols}; they expand to the matrix’ size. Similarly, \pgfkeysvalueof{/pgfplots/mesh/num points} expands to the total number of points.

      Inside of (math image)code for external program(math image), the macro \thecontournumber is defined to be the value \pgfkeysvalueof{/pgfplots/contour/number} and \thecontourlevels contains the value \pgfkeysvalueof{/pgfplots/contour/levels}. These two macros simplify conditional code.

      If you need one of the characters ["|;:#'`] and some macro package already uses the character for other purposes, you can prepend them with a backslash, i.e. write \" instead of ".

    • /pgfplots/contour external/script input format=x y meta meta|x y z meta (initially x y meta meta)

    • Defines what kind of input file the external script expects. Usually, contouring algorithms expect three coordinates and the last one is the one to which the contour computation is applied. Such algorithms need x y meta meta and the last coordinate needs to be ignored.

      However, there it is possible to define contour algorithms which expect four input coordinates (x,y,z,meta) where the fourth coordinate defines the contour level. In such a case, you have to use x y z meta as choice. A related key is output point meta in this context.

    • /pgfplots/contour external/script type=system call|lua (initially system call)

    • Allows to define the type of script. The choice system call invokes an external program. The choice lua writes the script into a lua file and invokes the lua interpreter. This is only supported if you use lualatex instead of pdflatex. It is unrelated to lua backend.

    • /pgfplots/contour external/@before cmd(initially empty)

    • /pgfplots/contour external/@after cmd(initially empty)

    • These keys allow callbacks for integrators. Any code inside of them is invoked before/after the script.

    • /pgfplots/contour external/script extension={(math image)extension(math image)} (initially script)

    • The file name extension for the temporary script.

    • /pgfplots/contour external/cmd={(math image)system call(math image)} (initially empty)

    • A template to generate system calls for the external program. Inside of (math image)system call(math image), you may use \script as placeholder for the filename which contains the result of contour external/script and \scriptbase as placeholder for the same, but without file extension.

    • /pgfplots/contour external/output point meta={(math image)point meta read from result of external tool(math image)} (initially empty)

    • Allows to customize the point meta configuration which is applied to the result of the external tool.

      In contour external, the value of point meta is used to generate the input \(z\)-coordinate for the external tool.

      As soon as the external tool computed contour lines, its output is read and interpreted as contour lines – and the value of output point meta determines the value of point meta which will be used to visualize the result.

      An empty value means to use the \(z\)-coordinate returned by the external tool.

      Any other value is interpreted as a valid choice of point meta.

    Note that contour external lacks the intelligence to detect changes; it will always regenerate the output (unless the -shell-escape feature is not active).

29 Note that contour lua processes the input stream only once. Consequently, the temporary file will contain only information which was available before the first point has been seen. The example above works because it contains emptylines as end-of-scanline markers. If you do not provide such markers, you may need to provide two of the three options mesh/rows, mesh/cols, or mesh/num points.

30 This is actually the output from our \addplot3[contour gnuplot] coordinates example from above.

4.6.9Filled Contour Plots

pgfplots is able to generate contour filled plots with its built-in arithmetics.

  • /pgfplots/contour filled={(math image)options with ‘contour/’ prefix(math image)}

  • \addplot+[ contour filled={(math image)options with ‘contour/’ prefix(math image)}]

Beware: Viewer Limitations

The following paragraph makes uses of pdf features which are unsupported by some free viewers (including pdf.js and evince). Please resort to a suitable viewer if you see unexpected results.

This plot handler visualizes patches or surfaces by means of filled segments: points on the surface will be colored based on their point meta value. The point meta value is mapped into a sequence of intervals, and each interval has its own color. The intervals, in turn, are part of a colormap.

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[colormap name=viridis,colorbar] \addplot3 [contour filled] {x^2*y}; \end{axis} \end{tikzpicture}

The number of contour levels is defined by means of contour/number, just as for contour external:

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[ title={$x \exp(-x^2-y^2)$}, domain=-2:2, view={0}{90}, colorbar horizontal, ] \addplot3 [ contour filled={ number=14, }, ] {exp(-x^2-y^2)*x}; \end{axis} \end{tikzpicture}

In addition to selecting a number of contour levels, you can select a predefined list of levels:

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[colormap/RdYlGn,colorbar, view={0}{90}] \addplot3 [domain=0:2*pi,trig format plots=rad, contour filled={ levels={-0.4,-0.25,0,0.3,0.9} }, ] {sin(x)*sin(y)}; \end{axis} \end{tikzpicture}

A filled contour plot merely affects the appearance of patch segments, so you can easily adopt axis options like view.

pgfplots implements the plot handler contour filled in almost the same way as surf: it expects the very same input format (i.e. coordinates in matrix form from any supported coordinate input stream) and expects numeric point meta. In order to determine the correct color, pgfplots evaluates point meta for each encountered vertex in the input matrix and interpolates any values of point meta on mesh segments. The interpolation scheme is normally linear, but you can write patch type=bilinear if you want bilinear interpolation of point meta (higher quality somewhat bigger output files; we come back to this at the end of this plot handler). Finally, each interpolated point meta is mapped into a colormap using colormap access=const.

The colormap in question is specific to contour filled: it is defined after the survey phase and is called internal:contourfilled. It is created using the of colormap functionality (see its reference for details). pgfplots uses target pos min and target pos max to ensure that the resulting colormap fits into the range point meta min\(:\)point meta max.

A contour filled plot comes with the following ways to define the contour limit positions:

  • 1. Defining the number of contour levels using contour/number={(math image)number(math image)},

  • 2. Defining a prescribed list of contour/levels={(math image)list(math image)},

  • 3. Defining the levels in levels from colormap in a suitable (math image)colormap definition(math image),

  • 4. Assigning empty values to all three of the items above in which case pgfplots will use as many contour levels as there are distinct colors in the current colormap.

As already mentioned, contour filled makes use of the same routines as mesh, surf, and patch plots. In particular, it requires z buffer=sort for the same reason as the surface plots:

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[view={60}{30},colormap/YlOrRd] \addplot3 [ contour filled={ number=7, }, point meta=x, z buffer=sort, samples=30,domain=-1:1,y domain=0:2*pi, ] ( {sqrt(1-x^2) * cos(deg(y))}, {sqrt( 1-x^2 ) * sin(deg(y))}, x ); \end{axis} \end{tikzpicture}

Note that contour filled only relies on point meta in order to determine contour levels. Consequently, it does not need contour dir; a simple point meta=x has the same effect (as is seen in the previous example).

A consequence of the fact that contour filled merely relies on point meta is that it supports two-dimensional plots as well, provided they have matrix structure and they provide point meta:

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} \addplot [ contour filled, point meta=explicit, ] coordinates { (0,0) [0] (1,0) [0] (2,0) [0] (3,0) [0] (0,1) [0] (1,1) [0.6] (2,1) [0.7] (3,1) [0.5] (0,2) [0] (1,2) [0.7] (2,2) [0.8] (3,2) [0.5] }; \end{axis} \end{tikzpicture}

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} \addplot3 [ contour filled, ] coordinates { (0,0,0) (1,0,0) (2,0,0) (3,0,0) (0,1,0) (1,1,0.6) (2,1,0.7) (3,1,0.5) (0,2,0) (1,2,0.7) (2,2,0.8) (3,2,0.5) }; \end{axis} \end{tikzpicture}

Quality considerations.

The results of contour filled always have smooth position interpolation at any resolution. Note that the quality of edges depends on the viewer application; Acrobat Reader appears to render results with high quality. Furthermore, the quality depends on the number of input samples (as always). However, contour filled plots of coarse grained input matrices can be improved by using a better color interpolation scheme: if you add patch type=bilinear for such plots, you typically get smoother results than the default triangle-based scheme:

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} % requires \usepgfplotslibrary{patchplots} \begin{tikzpicture} \begin{axis} \addplot [ contour filled, patch type=bilinear, point meta=explicit, ] coordinates { (0,0) [0] (1,0) [0] (2,0) [0] (3,0) [0] (0,1) [0] (1,1) [0.6] (2,1) [0.7] (3,1) [0.5] (0,2) [0] (1,2) [0.7] (2,2) [0.8] (3,2) [0.5] }; \end{axis} \end{tikzpicture}

Note that patch type=bilinear results in bigger output files and may take somewhat longer to render. It requires to load the patchplots library.

Limitations:

contour filled supports no contour labels and no contour outlines. Furthermore, its contour lines differ from the contours computed by contour lua.

31 Packed into the archive doc/latex/pgfplots/pgfplots.doc.src.tar.bz2. The file’s content has been imported from [5]; the precise link location is referenced in the data file itself.

32 You can play around with this example to see how the color is shifted if the ranges are not coupled.

4.6.10Parameterized Plots

Parameterized plots use the same plot types as documented in the preceding sections: both mesh and surface plots are actually special parameterized plots where \(x\) and \(y\) are on Cartesian grid points.

Parameterized plots just need a special way to provide the coordinates:

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[view={60}{30}] \addplot3+ [ domain=0:5*pi, samples=60, samples y=1, ] ( {sin(deg(x))}, {cos(deg(x))}, {2*x/(5*pi)} ); \end{axis} \end{tikzpicture}

The preceding example uses samples y=1 to indicate that a line shall be sampled instead of a matrix. The curly braces are necessary because can’t nest round braces. The single expressions here are used to parameterize the helix.

Another example follows. Note that z buffer=sort is a necessary method here.

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[view={60}{30}] \addplot3 [ mesh, z buffer=sort, samples=20, domain=-1:0, y domain=0:2*pi, ] ( {sqrt(1-x^2) * cos(deg(y))}, {sqrt( 1-x^2 ) * sin(deg(y))}, x ); \end{axis} \end{tikzpicture}

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[view={60}{30}] \addplot3 [ only marks, mesh,z buffer=sort, scatter,scatter src=z, samples=30,domain=-1:1,y domain=0:2*pi, ] ( {sqrt(1-x^2) * cos(deg(y))}, {sqrt( 1-x^2 ) * sin(deg(y))}, x ); \end{axis} \end{tikzpicture}

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[view={60}{30},colormap/viridis] \addplot3 [ surf,shader=interp,z buffer=sort, samples=30,domain=-1:0,y domain=0:2*pi, ] ( {sqrt(1-x^2) * cos(deg(y))}, {sqrt( 1-x^2 ) * sin(deg(y))}, x ); \end{axis} \end{tikzpicture}

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[ xlabel=$x$, ylabel=$y$, view/h=-10, title=Klein bottle, ] \addplot3 [ surf, z buffer=sort, colormap={periodic}{ color=(blue) color=(yellow) color=(orange) color=(red) color=(orange) color=(yellow) color=(blue)}, domain=0:180, domain y=0:360, samples=41, samples y=25, variable=\u, variable y=\v, point meta=u, ] ( {-2/15 * cos(u) * ( 3*cos(v) - 30*sin(u) + 90 *cos(u)^4 * sin(u) - 60 *cos(u)^6 * sin(u) + 5 * cos(u)*cos(v) * sin(u)) }, {-1/15 * sin(u) * (3*cos(v) - 3*cos(u)^2 * cos(v) - 48 * cos(u)^4*cos(v) + 48*cos(u)^6 *cos(v) - 60 *sin(u) + 5*cos(u)*cos(v)*sin(u) - 5*cos(u)^3 * cos(v) *sin(u) - 80*cos(u)^5 * cos(v)*sin(u) + 80*cos(u)^7 * cos(v) * sin(u)) }, {2/15 * (3 + 5*cos(u) *sin(u))*sin(v)} ); \end{axis} \end{tikzpicture}
4.6.113D Quiver Plots (Arrows)

Three dimensional quiver plots are possible with the same interface as their two-dimensional counterparts, simply provide the third coordinate using quiver/w. Please refer to Section 4.5.8 for details and examples.

4.6.12Image (Matrix) Plots
  • /pgfplots/matrix plot(no value)

Limitations:

Due to current implementational restrictions, matrix plot can only update axis limits successfully if the length of the matrix scanlines is known in advance. The example above contains mesh/cols=3, and a “scanline” is a row (with \(3\) columns each). Consequently, the example above works fine. However, If mesh/cols=3 would be unknown in advance, the current implementation assumes that end-of-scanline markers are given in the input file according to empty line=scanline. As a rule of thumb, you have to follow the following guidelines when using matrix plot:

  • 1. The input matrix should have an empty line whenever one line of input is finished.

  • 2. If there is no empty line, the length of each scanline must be given. For the standard configuration mesh/ordering=x varies, pgfplots expects mesh/cols. For the alternative choice mesh/ordering=y varies, pgfplots expects mesh/rows to be set.

  • 3. The input matrix must have at least \(2\) rows and at least \(2\) columns. This allows pgfplots to interpolate/extrapolate the vertices in a well-defined way.

If both of the first two conditions are violated, pgfplots fails to update the limits correctly and generates the warning

Package pgfplots Warning: Automatic computation of axis limits for 'matrix plot' is INACCURATE. Please add the key 'mesh/cols=3'. You can also ignore this warning and deal with axis limits manually

If you encounter this warning, you should proceed according to the guidelines above or ignore the warning and configure ymin and ymax manually.

A matrix plot expects a complete matrix on input; it is forbidden to leave holes in it. However, it supports “invisible” cells: provide unbounded values for point meta in order to produce a “hole” in the lattice:

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[enlargelimits=false,colorbar] \addplot [ matrix plot, nodes near coords=\coordindex,mark=*, point meta=explicit, ] coordinates { (0,0) [0] (1,0) [1] (2,0) [2] (0,1) [3] (1,1) [nan] (2,1) [5] (0,2) [6] (1,2) [7] (2,2) [8] }; \end{axis} \end{tikzpicture}

Here, “unbounded” means a color value which is nan (not a number), inf, or -inf. In case of mesh/color input=explicit, you can simply provide an empty explicit color to achieve the same effect:

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[enlargelimits=false] \addplot [ matrix plot, mark=*,nodes near coords=\coordindex, mesh/color input=explicit, ] coordinates { (0,0) [color=red] (1,0) [color=blue] (2,0) [color=yellow] (0,1) [color=black] (1,1) [] (2,1) [color=magenta] (0,2) [color=green] (1,2) [color=red] (2,2) [color=white] }; \end{axis} \end{tikzpicture}

This feature works for shader=flat mean or shader=interp as well. However, these shaders require color interpolation in order to determine the correct color for the visible cells. In this case, the missing cell will be replaced by the lowest possible point meta (or by black in case of mesh/color input=explicit), resulting in the following output:

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[enlargelimits=false,colorbar] \addplot [matrix plot, shader=interp, point meta=explicit, ] coordinates { (0,0) [0] (1,0) [1] (2,0) [2] (0,1) [3] (1,1) [nan] (2,1) [5] (0,2) [6] (1,2) [7] (2,2) [8] }; \end{axis} \end{tikzpicture}

A matrix plot will always be connected, even if the vertices form a distorted mesh. The input must be a complete matrix, but its \(x\)- and \(y\)-coordinates (or maybe even \(z\)-coordinates) can still be different from what one expects from a matrix. The resulting cells are produced using interpolation/extrapolation:

(-tikz- diagram)

% Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[enlargelimits=0.2,colorbar] \addplot [ matrix plot, nodes near coords=\coordindex,mark=*, point meta=\coordindex, ] table { x y 0 0 1 -0.1 2 0.2 -0.2 1 1 1 2 1 0 2 1.3 2 2 2.5 }; \end{axis} \end{tikzpicture}

Note that the expected usage of matrix plot is to have something which is at least close to a matrix, and the axis limits may become inaccurate if the input forms a highly irregular mesh. In particular, the axis limits in \(z\) direction are highly inaccurate for matrix plots, but the visualization is precise. Applying matrix plot to a three-dimensional input might also need z buffer=auto since matrix plot disables z buffer by default (in order to ensure correct color associations, i.e. to avoid reorderings). If you really need three-dimensional matrix plots, you may want to specify surf,mesh input=image directly, and you may need to adopt axis limits manually. The main use case of matrix plot is for input which looks roughly like an image.

Technically, matrix plot is a style which configures y dir=reverse and axis on top as outlined above, and which installs matrix plot* afterwards.

See also colormap access=direct for examples how to use matrix plot in conjunction with bitmap graphics.

  • /tikz/matrix plot*(no value)

  • /tikz/imagesc(no value)

  • \addplot+[imagesc]

  • A pure alias for matrix plot because imagesc is the reference to this type of plot in other applications.

  • /tikz/imagesc*(no value)

4.6.13Patch Plots
  • /pgfplots/patch(no value)

  • \addplot+[patch]

  • Patch plots are similar to mesh and surf plots in that they describe a filled area by means of a geometry.

    However, patch plots are defined by explicitly providing the elements of the geometry: they expect a sequence of triangles (or other patch types) which make up the mesh.

    There are two dimensional and three dimensional patch plots, both with the same interfaces which are explained in the following sections.

    The standard input format (constituted by mesh input=patches) is to provide a sequence of coordinates (either two- or three-dimensional) as usual. Each consecutive set of points makes up a patch element, which is often a triangle:

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} \addplot [patch] table { x y 0 0 1 1 2 0 % empty lines do not hurt, they are ignored here: 1 1 2 0 3 1 2 0 3 1 4 0 }; \end{axis} \end{tikzpicture}

    Patch plots use point meta to determine fill colors. In its initial configuration, point meta will be set to the \(y\)-coordinate (or the \(z\)-coordinate for three dimensional patch plots). Set point meta somehow to color the patches:

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} \addplot [patch] table [point meta=\thisrow{c}] { x y c 0 0 0.2 1 1 0 2 0 1 1 1 0 2 0 1 3 1 0 2 0 1 3 1 0 4 0 0.5 }; \end{axis} \end{tikzpicture}

    Patch plots make use of the mesh configuration, including the shader. Thus, the example above uses the initial shader=faceted (which uses the mean color data to determine a triangle’s color and a related stroke color). The shader=interp yields the following result:

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} \addplot [patch,shader=interp] table [point meta=\thisrow{c}] { x y c 0 0 0.2 1 1 0 2 0 1 1 1 0 2 0 1 3 1 0 2 0 1 3 1 0 4 0 0.5 }; \end{axis} \end{tikzpicture}

    For triangles, shader=interp results in linearly interpolated point meta values throughout each individual triangle, which are then mapped to the color map (a technique also known as Gouraud shading).

    The color data does not need to be continuous, it is associated to triangle vertices. Thus, changing some of the color values allows individually shaded regions:

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} \addplot [patch,shader=interp] table [point meta=\thisrow{c}] { x y c 0 0 0.2 1 1 0 2 0 1 1 1 0 2 0 -1 3 1 0 2 0 0.5 3 1 1 4 0 0.5 }; \end{axis} \end{tikzpicture}

    Two dimensional patch plots simply draw triangles in their order of appearance. In three dimensions, single elements are sorted according to their view depth, with foreground elements drawn on top of background elements (“Painter’s algorithm”, see z buffer=sort).

    • /pgfplots/patch table={(math image)table file name or inline table(math image)} (initially empty)

    • /pgfplots/patch table with point meta={(math image)table file name or inline table(math image)} (initially empty)

    • /pgfplots/patch table with individual point meta={(math image)table file name or inline table(math image)} (initially empty)

    • Allows to provide patch connectivity data stored in an input table.

      A non-empty argument for patch table enables patch input mode. Now, the standard input stream is a long list of vertices which are stored in an array using their \coordindex as key. Each row of (math image)table file name or inline table(math image) makes up one patch, defined by indices into the vertex array:

      (-tikz- diagram)

      % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} \addplot [patch,table/row sep=\\,patch table={ 0 1 2\\ 1 2 3\\ 4 3 5\\ }] table [row sep=\\,point meta=\thisrow{c}] { x y c \\ 0 0 0.2\\% 0 1 1 0 \\% 1 2 0 1 \\% 2 3 1 0 \\% 3 2 0 0.5\\% 4 4 0 0.5\\% 5 }; \end{axis} \end{tikzpicture}

      The example consists of two separate tables. The patch table argument is a table, provided inline where rows are separated by \\ (which is the purpose of the row sep=\\ key as you guessed).33 The patch table here declares three triangles: the triangle made up by vertex \(\#0\), \(\#1\) and \(\#2\), the triangle made up by \(\#1\), \(\#2\) and \(\#3\) and finally the one using the vertices \(\#4\), \(\#3\) and \(\#5\). The vertices as such are provided using the standard input methods of pgfplots; in our case using a table as well. The standard input simply provides coordinates (and point meta) which are stored in the vertex array; you could also have used \addplot coordinates to provide them (or \addplot expression).

      The argument to patch table needs to be a table – either a file name or an inline table as in the example above. The first \(n\) columns of this table are assumed to contain indices into the vertex array (which is made up using all vertices of the standard input as explained in the previous paragraph). The entries in this table can be provided in floating point, just make sure they are not rounded. The variable \(n\) is the number of vertices required to make up a single patch. For triangular patches, it is \(n=3\), for patch type=bilinear it is \(n=4\) and similar for other choices of patch type.

      The alternative patch table with point meta is almost the same as patch table – but it allows to provide (a single) point meta (color data) per patch instead of per vertex. Here, a further column of the argument table is interpreted as color data:

      (-tikz- diagram)

      % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} % this uses per-patch color data: \addplot [patch,table/row sep=\\, patch table with point meta={ 0 1 2 100\\ 1 2 3 10\\ 4 3 5 0\\ }, ] table [row sep=\\] { x y \\ 0 0 \\% 0 1 1 \\% 1 2 0 \\% 2 3 1 \\% 3 2 0 \\% 4 4 0 \\% 5 }; \end{axis} \end{tikzpicture}

      The patch table with point meta always prefers point meta data from the provided table argument. However, it is still supported to write point meta=\thisrow{(math image)colname(math image)} or similar constructs – but now, (math image)colname(math image) refers to the provided table argument. More precisely, point meta is evaluated in a context where the patch connectivity has been resolved and the patch table with point meta is loaded.

      The other alternative patch table with individual point meta is very similar, but instead of a flat color per patch, it allows to write one color value for every patch:

      (-tikz- diagram)

      % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} % this uses n per-patch color values: \addplot[patch,shader=interp, table/row sep=\\, patch table with individual point meta={ % V_0 V_1 V_2 C_0 C_1 C_2 0 1 2 100 100 100 \\ 1 2 3 10 0 50 \\ 4 3 5 0 0 100 \\ }] table[row sep=\\] { x y \\ 0 0 \\% 0 1 1 \\% 1 2 0 \\% 2 3 1 \\% 3 2 0 \\% 4 4 0 \\% 5 }; \end{axis} \end{tikzpicture}

      To find the point meta data for vertex \(\#i, i=0,1,2\), pgfplots searches in column \(i+n\) where \(n\) is the number of vertices for patch type (in our case, \(n=3\)).

      Technical remark: The key patch table with individual point meta automatically installs point meta=explicit as well. It might be confusing to override the value of point meta here (although it is allowed).

      The patch table input type allows to reduce the size of geometries since vertices are stored just once. pgfplots unpacks them into memory into the redundant format in order to work with single patch elements.34 In case you experience memory problems with this connectivity input, consider using the redundant format. It uses other types of memory limits.

    A more involved example is shown below; it uses \addplot3[patch] to visualize a three dimensional patch plot, provided by means of a long sequence of patches:

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[axis equal] % FokkerDrI_layer_0.patches.dat contains: % # each row is one vertex; three consecutive % # vertices make one triangle (patch) % 105.577 -19.7332 2.85249 % 88.9233 -21.1254 13.0359 % 89.2104 -22.1547 1.46467 % # end of facet 0 % 105.577 -19.7332 2.85249 % 105.577 -17.2161 12.146 % 88.9233 -21.1254 13.0359 % # end of facet 1 \addplot3 [patch] file {plotdata/FokkerDrI_layer_0.patches.dat}; \end{axis} \end{tikzpicture}

    The ordering in which triangles are specified is irrelevant, three-dimensional patch plots use z buffer=sort to sort patches according to their depth (defined as mean depth over each vertex), where foreground patches are drawn on top of background patches. This so-called “Painter’s algorithm” works well for most meshes. If it fails, consider using patch refines=1 or patch refines=2 to split larger elements into small ones automatically.

    The drawing color associated to single vertices can be changed using the point meta key (which is the common method to configure color data in pgfplots). The initial configuration is point meta=z for three dimensional patch plots, i.e. to use the \(z\)-coordinate also as color data. Use point meta=\thisrow{(math image)colname(math image)} in conjunction with \addplot3[patch] table to load a selected table column.

    Patch plots are (almost) the same as mesh or surf plots, they only have more freedom in their input format (and a more complicated geometry). Actually, “patch” is just a style for surf,mesh input=patches. In other words, patch is the same as surf, it even shares the same internal implementation. Thus, most of the keys to configure mesh or surf plots apply to patch as well, especially shader and z buffer. As already mentioned, \addplot3[patch] automatically activates z buffer=sort to ensure a good drawing sequence. The shader can be used to modify the appearance:

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis} % FokkerDrI_layer_0.facetIdx.dat contains: % # each row makes up one facet; it % # consists of 0-based indices into % # the vertex array % 0 1 2 % triangle of vertices #0,#1 and #2 % 0 3 1 % triangle of vertices #0,#3 and #1 % 3 4 1 % 5 6 7 % 6 8 7 % 8 9 7 % 8 10 9 % ... % while FokkerDrI_layer_0.vertices.dat contains % 105.577 -19.7332 2.85249 % vertex #0 % 88.9233 -21.1254 13.0359 % vertex #1 % 89.2104 -22.1547 1.46467 % vertex #2 % 105.577 -17.2161 12.146 % 105.577 -10.6054 18.7567 % 105.577 7.98161 18.7567 % 105.577 14.5923 12.146 % ... \addplot3 [patch,shader=interp, patch table= {plotdata/FokkerDrI_layer_0.facetIdx.dat}] file {plotdata/FokkerDrI_layer_0.vertices.dat}; \end{axis} \end{tikzpicture}

    See the description of shader=interp for details and remarks. The example above makes use of the alternative syntax to provide a geometry: the patch table input. It allows to provide vertices separate from patch connectivity, where each patch is defined using three indices into the vertex array as discussed above.

    (-tikz- diagram)

    % Preamble: \pgfplotsset{width=7cm,compat=1.18} \begin{tikzpicture} \begin{axis}[view/h=70] % FokkerDrI_layer_0.patches.dat contains: % # each row is one vertex; three consecutive % # vertices make one triangle (patch) % 105.577 -19.7332 2.85249 % 88.9233 -21.1254 13.0359 % 89.2104 -22.1547 1.46467 % # end of facet 0 % 105.577 -19.7332 2.85249 % 105.577 -17.2161 12.146 % 88.9233 -21.1254 13.0359 % # end of facet 1 \addplot3 [patch,mesh] file {plotdata/FokkerDrI_layer_0.patches.dat}; \end{axis} \end{tikzpicture}
    • /pgfplots/mesh input=lattice|patches|image

    • This key controls how input coordinates are decoded to get patches. It is used only if patch table is empty (patch table has its own way to decode input coordinates). Usually, you won’t need to bother with this key as it is set implicitly.

      The choice mesh input=lattice is the initial configuration for mesh and surf plots: it expects input in a compact matrix form as described at the beginning of this section and requires a mesh/ordering and perhaps end-of-scanline markers. It yields patches with exactly four corners and is compatible with patch type=rectangle and patch type=bilinear (the latter requiring to load the patchplots library). In this case, the input stream contains the vertices.

      The choice mesh input=patches is implicitly set when you use the patch style (remember that surf is actually some sort of patch plot on its own). It expects the input format as described for patch plots, i.e. \(n\) consecutive coordinates make up the vertices of a single patch where \(n\) is the expected number of vertices for the configured patch type.

      The choice mesh input=image implements matrix plot: it expects input in the same technical format as for mesh input=lattice (i.e. using end-of-scanline markers, mesh/ordering, etc), but the coordinates are interpreted as patch mid points. It yields patches with exactly four corners and is compatible with patch type=rectangle and patch type=bilinear. The patches are generated by interpolating the coordinates between adjacent cell mid points. Vertices which have only one adjacent cell mid point are extrapolated. This choice is unsupported for one-dimensional inputs, i.e. for lines or for \(1\times n\) or \(n \times 1\) matrices. See matrix plot for more details.

      Note that a non-empty patch table implies mesh input=patches.

    • /pgfplots/every patch(style, no value)

    • This style will be installed as soon as the patch plot handler is activated.

      The initial configuration is

      which improves display of sharp triangle corners significantly (see the TikZ manual for details about miter limit and line join parameters).

    There is much more to say about patch plots, like patch type which allows triangles, bilinear elements, quadratic triangles, biquadratic quadrilaterals, coons patches; the patch refines key which allows automatic refinement, patch to triangles which triangulates higher order elements; how matrix data can be used for rectangular shapes and more. These details are subject of the patchplots library in Section 5.9.

33 Note that the choice row sep=\\ is much more robust here: newlines would be converted to spaces by before pgfplots had a chance to see them.

34 The reason for such an approach is that doesn’t really know what an array is – and according to my experience, arrays implemented by macros tend to blow up ’s memory limits even faster than the alternative.

4.6.14About 3D Const Plots and 3D Bar Plots

There are currently no equivalents of const plot and its variants or the bar plot types like ybar for three dimensional axes, sorry.

4.6.15Mesh/Surface Plots with Holes

Please refer to Section 4.5.14 for interrupted plots.