Use asymptote
, this is a more appropriate tool for plotting in 3D.
With some additional work you can make it look like a pgfplots
graph.
Below there are three ways of doing this with asymptote
.
Transparent surfaces

settings.outformat="png";
settings.render=16;
import graph3;
import palette;
size3(150,IgnoreAspect);
currentprojection=orthographic(50,-60,0.4);
currentlight=(5,-3,1);
real f(pair z){return (1.-0.3)*exp(-z.x*(z.y/100.)*(1.-0.3))-exp(-z.x*(z.y/100.));}
real cero(pair z){return 0.;}
limits((0,0,-0.3),(30,30,0.1));
xaxis3(Label("$x$",1),blue,arrow=Arrow3);
yaxis3(Label("$y$",1),blue,arrow=Arrow3);
zaxis3(Label("$z$",1),blue,arrow=Arrow3);
surface s=surface(f,(0,0),(30,30),30,30,Spline);
surface s2=surface(cero,(0,0),(30,30),30,30,Spline);
s.colors(palette(s.map(zpart),Rainbow()+opacity(0.5)));
s2.colors(palette(s2.map(zpart),Rainbow()+opacity(0.5)));
draw(s,meshpen=blue);
draw(s2,meshpen=red);
shipout(bbox(2mm,Fill(white)));
Solid surfaces

settings.outformat="png";
settings.render=16;
import graph3;
import palette;
size3(150,IgnoreAspect);
currentprojection=orthographic(50,-60,0.4);
//currentlight=(-5,3,20);
real f(pair z){return (1.-0.3)*exp(-z.x*(z.y/100.)*(1.-0.3))-exp(-z.x*(z.y/100.));}
real cero(pair z){return 0.;}
limits((0,0,-0.3),(30,30,0.1));
xaxis3(Label("$x$",1),blue,arrow=Arrow3);
yaxis3(Label("$y$",1),blue,arrow=Arrow3);
zaxis3(Label("$z$",1),blue,arrow=Arrow3);
surface s=surface(f,(0,0),(30,30),30,30,Spline);
surface s2=surface(cero,(0,0),(30,30),30,30,Spline);
//s.colors(palette(s.map(zpart),Rainbow+opacity(0.5)));
//s2.colors(palette(s2.map(zpart),Rainbow()+opacity(0.5)));
draw(s, blue,meshpen=blue);
draw(s2, red, meshpen=red);
shipout(bbox(2mm,Fill(white)));
PGFplots style (still with Asymptote)
This is the closest I was able to make it look like a pgfplots
plot.
(Things to do, help is welcomed: 1) automatic point of view (to not depend on the scale of the plot, 2) thick border around each surface 3) vector graphics and hidden surface (e.g. via bsd
module) 4) details, like small tics and tics spacing)

settings.outformat="png";
settings.render=8;
import grid3;
import graph3;
import palette;
size3(160,125,90,IgnoreAspect);
currentprojection=orthographic(30,-60,0.8);
real f(pair z){return (1.-0.3)*exp(-z.x*(z.y/100.)*(1.-0.3))-exp(-z.x*(z.y/100.));}
real cero(pair z){return 0.;}
limits((0,0,-0.3),(30,30,0.1));
xaxis3(Bounds(Min,Min), InTicks());
xaxis3(Bounds(Max,Max));
xaxis3(Bounds(Max,Min));
yaxis3(Bounds(Max,Min), InTicks(beginlabel=false) );
yaxis3(Bounds(Min,Max));
yaxis3(Bounds(Min,Min));
zaxis3(Bounds(Min,Min), InTicks() );
zaxis3(Bounds(Max,Max));
zaxis3(Bounds(Min,Max));
surface s=surface(f,(0,0),(30,30),24,24);
surface s2=surface(cero,(0,0),(30,30),24,24);
draw(s, mean(palette(s.map(zpart),Gradient(blue,yellow,red))),meshpen=0.2pt + black, nolight);
draw(s2, red, meshpen=0.2pt + black, nolight);
draw(s2, red, meshpen=0.2pt + black, nolight);
shipout(bbox(2mm,Fill(white)));
Notes
asymptote
can output vector graphics, but the output is not as good as a raster (rendered) output and removal of hidden faces is very difficult (like with pgfplots
.)
So, this is big drawback of using asymptote, the plot becomes raster.
However, it is common that 3D plots quickly become too complex to render with vector graphics.
\addplot3 graphics
: golatex.de/… (in german only - but pictures speak in their own language, I guess)