[Tex/LaTex] pgfplots: color a (3D) surf using arbitrary RGB colors

3dcolorgradientpgfplots

I would like to color a surf using arbitrary RGB colors (unlike this question, which just colors the surf using the colormap).

In this minimal example (which plots the x+y function), I would like the color of each patch to be red=x, green=y, blue=x*y for example.

Bonus points if I can also set the opacity :) .

I think this can be done using point meta=explicit symbolic or point meta=Tex code symbolic, but I don't know how to use the metadata afterwards.

\documentclass{article}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=1.7}
\usepgfplotslibrary{patchplots}
\begin{document}

\begin{tikzpicture}
  \begin{axis}
    \addplot3[surf] { x + y };
  \end{axis}
\end{tikzpicture}

\end{document}

Best Answer

Pgfplots up to and including version 1.7 only supports colors by means of a colormap.

EDIT this restriction applies to mesh/surface plots, special scatter plots might work.

You are the second user requesting this feature. I accept that as a feature request.

It is good to know that you would like to express RGB components in dependence of the parameters x and y. I suppose one would also like to provide colors using the syntax of xcolor, so the color format should probably be flexible enough to support both.

Edit by Georges Dupéron

For those impatient to try, you can check out the (probably bleeding edge) version of Christian's pgfplots :

# Create a temporary working directory.
workdir="/tmp/$(date +%s)"
mkdir "$workdir"
# Download the latest (as of 2013-02-13) unstable version of PGF
mkdir "$workdir/pgf"
cd "$workdir/pgf";
wget http://www.texample.net/media/pgf/builds/pgfCVS2012-11-04_TDS.tgz -O- | tar zxvf -
# Download the latest version of pgfplots
cd "$workdir"
git clone git://pgfplots.git.sourceforge.net/gitroot/pgfplots/pgfplots
# Tell LaTeX to use these versions
export TEXINPUTS="$workdir/pgf/tex//:$workdir/pgfplots//:"
cd "$workdir/pgfplots"
# Add a dummy tag so we can run pgfplotsrevisionfile.sh, which is required to use pgfplots
git tag 1.7.42
./scripts/pgfplots/pgfplotsrevisionfile.sh
# Compile a small example that plots x*y with red=x, green=y and blue=0
pdflatex source/latex/pgfplots/pgfplotstest/unittests/unittest_shader_interp_explicitcolor_math.tex
# View the resulting PDF
evince unittest_shader_interp_explicitcolor_math.pdf

The result (plot x*y with mesh/color input=explicit mathparse, point meta/symbolic={x,y,0}):

plot x*y with red=x, green=y and blue=0

\documentclass[a4paper]{article}

\usepackage{pgfplots}

\usepgfplotslibrary{patchplots}
\pgfplotsset{compat=1.8}

\begin{document}

\begin{tikzpicture}
%\tracingmacros=2 \tracingcommands=2
\begin{axis}
    \addplot3[
        patch,
        patch type=bilinear,
        shader=interp,
        mesh/color input=explicit mathparse,
        domain=0:1,
        samples=5,
        point meta/symbolic={x,y,0}
        ]
    {x*y};
\end{axis}
\end{tikzpicture}

\end{document}

Another example (plot sin(deg(x*pi*2))+sin(deg(y*pi*2)) with mesh/color input=explicit mathparse, point meta/symbolic={(sin(deg(x*pi*2))+1)/2,(sin(deg(y*pi*2))+1)/2,0}, after having plot -3 with the same colors):

plot sin(x)+sin(y) with red=sin(x), green=sin(y) and blue=0, and -3 with the same colors

\documentclass[a4paper]{article}

\usepackage{pgfplots}

\usepgfplotslibrary{patchplots}
\pgfplotsset{compat=1.8}

\begin{document}

\begin{tikzpicture}
%\tracingmacros=2 \tracingcommands=2
\begin{axis}
    \addplot3[
        patch,
        patch type=bilinear,
        shader=faceted interp,
        mesh/color input=explicit mathparse,
        domain=0:1,
        samples=30,
        point meta/symbolic={(sin(deg(x*pi*2))+1)/2,(sin(deg(y*pi*2))+1)/2,0}
        ]
    {-3};
    \addplot3[
        patch,
        patch type=bilinear,
        shader=faceted interp,
        mesh/color input=explicit mathparse,
        domain=0:1,
        samples=30,
        point meta/symbolic={(sin(deg(x*pi*2))+1)/2,(sin(deg(y*pi*2))+1)/2,0}
        ]
    {sin(deg(x*pi*2))+sin(deg(y*pi*2))};
\end{axis}
\end{tikzpicture}

\end{document}