Both contour and 3d plots can be done easily in pgfplots, but I have a hard time combining them nicely.
Here's an example of what I'd like to achieve (from the matplotlib examples):

Both contour and 3d plots can be done easily in pgfplots, but I have a hard time combining them nicely.
Here's an example of what I'd like to achieve (from the matplotlib examples):

Pgfplots can compute the z contours by means of gnuplot and its contour gnuplot interface.
The projection onto the x axis (i.e. with fixed y) can be done by means of a matrix line plot in which you replace the y coordinate of the input matrix by some fixed constant.
The projection onto the y axis (i.e. with fixed x) is more involved (at least if mesh/ordering=x varies as in my example below) because one needs to transpose the input matrix. In my example below, I simply replaced the meaning of x and y to achieve the transposal. This, of course, would be more involved for a data matrix (and I think that pgfplots has no builtin to do it).
Here is what I got so far:

\documentclass{standalone}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
domain=-2:2,
domain y=0:2*pi,
]
\newcommand\expr[2]{exp(-#1^2) * sin(deg(#2))}
\addplot3[
contour gnuplot={
% cdata should not be affected by z filter:
output point meta=rawz,
number=10,
labels=false,
},
samples=41,
z filter/.code=\def\pgfmathresult{-1.6},
]
{\expr{x}{y}};
\addplot3[
samples=41,
samples y=10,
domain=0:2*pi,
domain y=-2:2,
% we want 1d (!) individually colored mesh segments:
mesh, patch type=line,
x filter/.code=\def\pgfmathresult{-2.5},
]
(y,x,{\expr{y}{x}});
\addplot3[
samples=41,
samples y=10,
% we want 1d (!) individually colored mesh segments:
mesh, patch type=line,
y filter/.code=\def\pgfmathresult{8},
]
{\expr{x}{y}};
\addplot3[surf,samples=25]
{\expr{x}{y}};
\end{axis}
\end{tikzpicture}
\end{document}
As you see, the first contour is the z contour. It is computed using gnuplot (and requires the -shell-escape mechanism to this end!).
The x and y projections are computed using the same matrix of function values. I chose a different sampling density to control how many "contour lines" shall be drawn. Note that these lines are conceptionally different from the z contours: they are already part of the sampling procedure and do not need to be computed externally. Note that I used mesh, patch type=line to tell pgfplots that (a) it should use individually colored segments and (b) it should not color the 2d structure, just the lines in scanline order (which is mesh/ordering=x varies in my case).
plot3 to also make the side projections. (I can't compete with the master.) @ChristianFeuersanger: Do you plan to bring native contour plots to pgfplots or is it beyond the scope? If so, what algorithm would you use to implement it?
– alfC
Dec 22 '12 at 02:12
splot ... using 1:3:2 or something like that. I will think about a suitable pgfplots option.
– Christian Feuersänger
Dec 22 '12 at 07:29
contour dir=x|y|z). It is currently part of the unstable (cf http://pgfplots.sourceforge.net/).
– Christian Feuersänger
Dec 29 '12 at 09:53
pgfplot supports contour plots by using the external-gnuplot. The side curves are obtained by two parametric curves. You can combine the 4 plots by putting all of them inside the axis environment.
The code is redundant, specially because the function in gnuplot (which does the contour) can not be passed from the tex code, as far as I know.
The result is the following:

The code follows:
\documentclass{scrartcl}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
\begin{axis}[domain=-5:5]
\addplot3[domain=-5:5,samples=80,samples y=0,mark=none,black, opacity=0.5,thick]({x},{6.},{exp(-x*x - 0*0 + x*0. + 0.)});
\addplot3[domain=-5:5,samples=80,samples y=0,mark=none,black, opacity=0.5,thick]({-6.},{x},{exp(-0*0 - x*x + 0.*x + x)});
\addplot3 +[no markers,
raw gnuplot,
mesh=false,
z filter/.code={\def\pgfmathresult{-2}}
] gnuplot {
set contour base;
set cntrparam levels 20;
unset surface;
set view map;
set isosamples 500;
set samples 100;
splot [-5:5][-5:5][0:1] exp(-x*x-y*y + x*y + y);
};
\end{axis}
\addplot3[surf,opacity=0.5,samples=40] {exp(-x*x-y*y + x*y + y)};
\end{tikzpicture}
\end{document}
\addplot3 at the end of all \addplot3s? The surf plot is always on top? Nonetheless opacity should be included anyway to show hidden contour lines.
– Qrrbrbirlbel
Dec 20 '12 at 04:46
opacity simply because that is what is shown in the example of the question. Admittedly the OP probably wants a fully automatic solution, but I don't know how to do that, I mention that in the new answer.
– alfC
Dec 20 '12 at 05:54
here is a solution with pst-solides3d for the function z=sin(x)*sin(y), which can be adopted to your function.
\documentclass[12pt]{article}
\usepackage{pst-solides3d}
\pagestyle{empty}
\begin{document}
\psset{arrowlength=3,arrowinset=0,viewpoint=50 30 20 rtp2xyz,Decran=50,
lightsrc=viewpoint}
\begin{pspicture}(-7,-8)(7,8)
\axesIIID[linecolor=gray](0,0,0)(7,7,7)
\psSolid[ngrid=.3 .3,object=grille,base=1 8 1 8,
linewidth=0.4pt,linecolor=gray!50,action=draw]%
{\psset{object=courbe,r=0,linecolor=blue,resolution=360,function=Fxy}
\multido{\rA=0.0+1.0}{8}{%
\defFunction[algebraic]{Fxy}(x){x}{0}{sin(x)*sin(\rA)+3}
\psSolid[range=1 8]}
\multido{\rA=0.0+1.0}{8}{%
\defFunction[algebraic]{Fxy}(y){0}{y}{sin(\rA)*sin(y)+3}
\psSolid[range=1 8]}}
\psSurface[ngrid=.3 .3,fillcolor=green!30,incolor=gray!30,
linewidth=0.4pt,algebraic](1,1)(8,8){ sin(x)*sin(y) +3 }
\end{pspicture}
\end{document}

and the same for a more complicated funktion:
