# A good METAPOST alternative for plotting 3d surfaces

I find METAPOST to be a wonderful software to create 2d charts and figures.

Can you name me a few good alternatives to METAPOST for drawing 3d surfaces?

The crucial feature I'm looking for is the ability to have all the fonts (the axis labels and all the numbers) in the LaTeX font, just like METAPOST so gracefully allows me to do.

## 4 Answers

For powerful graphics I would recommend Asymptote. It has a C++-type object-oriented syntax and is not that difficult to learn. Some of the main strong points are (but look at the gallery on the webpage):

• Full math and linear algebra engine
• Full 3D including active 3D pictures in PDF
• Use LaTeX to set all text and math
• It can be inlined in Latex but it is normaly better to use it for standalone graphics.

Here is a nice one from the gallery of Asymptote examples by Gaétan Marris

with the code that generated it

import graph3;
import contour;
import grid3;
import palette;

size(8cm,IgnoreAspect);
currentprojection=orthographic(-10,-10,8);
limits((0,0,0),(5,10,12));

real f(pair z) {return (z.x+z.y)/(2+cos(z.x)*sin(z.y));}
real[] lignesniveaux={2,4,6,8};
surface s=surface(f,(0,0),(5,10),50,Spline);

draw(s,mean(palette(s.map(zpart),Rainbow())),black);

grid3(new grid3routines [] {XYXgrid, ZXgrid(10), ZYgrid(5)},
Step=2,
step=1,
pGrid=new pen[] {red, blue, black},
pgrid=new pen[] {0.5red, lightgray, lightgray});
xaxis3(Label("$x$",position=MidPoint,align=SE),
Bounds(Min,Min),
OutTicks());
yaxis3(Label("$y$",position=MidPoint,align=SW),
Bounds(Min,Min),
OutTicks(Step=2));
zaxis3(Bounds(Max,Both));
zaxis3(Label("$z$",position=EndPoint,align=N+W),
XYEquals(0,10),
InTicks(beginlabel=false,endlabel=false,Label(align=Y)));

draw(lift(f,contour(f,(0,0),(5,10),lignesniveaux)),1bp+red);

• Is there a way to get these plots to look more like in the METAPOST solution of DJP? (With black curves throughout the surface, and dotted lines on the axis-planes.) – meh May 6 '12 at 13:39
• @meh: Yes you can customize Asymptote for anything. Look at the examples supplied on the links page. I normaly write a set of standard templates for frames, grids, text, etc. and then use it for all the graphs in my document (by using the import command). This way you can ensure a consistent look for al the graphs in a document. – Danie Els May 6 '12 at 15:37

What's wrong with using METAPOST for 3d surfaces? You can create them easily here. Click on the tab and set it to "3D Two Variable Function Surface". Click on "Example 2" and you should see this

Those are beautiful 3D graphics with axis labels and numbers.... Note: mousing over the picture will give you the ability to rotate to the view you think is best.

• I've taken a look at the source to that figure and it is awfully long: 15k lines of code in the Context version... I guess that is code written by code. – Charles Stewart Mar 16 '13 at 22:21
• It is very limitited, say you can not draw a two surfaces and mark their intersection. – Anton Petrunin Mar 27 at 2:51

A good METAPOST alternative for plotting 3D surfaces is PSTricks.

The following code used pst-solides3d package which is one of many PSTricks packages.

% Compile this with either xelatex or latex->dvips->ps2pdf
\documentclass{article}
\usepackage{pst-solides3d}
\psset{unit=2}

\usepackage[active,tightpage]{preview}
\PreviewBorder=12pt
\PreviewEnvironment{pspicture}

\begin{document}
\begin{pspicture}[showgrid=false](-3,-2)(3,3)
\psset[pst-solides3d]{viewpoint=20 20 20 rtp2xyz,Decran=20,lightsrc=viewpoint}
\psSolid[object=grille,base=-2 2 -2 2,action=draw,linecolor=red](0,0,0)
\axesIIID(2,2,1.5)(3,2.5,2.5)
\defFunction[algebraic]{sphere}(u,v){2*cos(u)*cos(v)} {2*sin(u)*cos(v)} {2*sin(v)}
\psSolid[object=surfaceparametree,base=pi neg pi 0 0.8,hue=0.2 0.8,function=sphere,linewidth=0.2pt,opacity=0.8,ngrid=0.1]
\end{pspicture}
\end{document}


Compiling the code with either xelatex or latex->dvips->ps2pdf, we will get the following output.

## Miscellaneous

More exciting code with animation:

% Compile this with either xelatex or latex->dvips->ps2pdf
\documentclass{article}
\usepackage{pst-solides3d}
\psset{unit=2}

\usepackage[active,tightpage]{preview}
\PreviewBorder=12pt
\PreviewEnvironment{pspicture}

\usepackage{multido}

\begin{document}
\multido{\r=0.0+0.4,\i=0+1}{6}{
\begin{pspicture}[showgrid=false](-3,-2)(3,3)
\psset[pst-solides3d]{viewpoint=20 20 20 rtp2xyz,Decran=20,lightsrc=viewpoint}
\psSolid[object=grille,base=-2 2 -2 2,action=draw,linecolor=red](0,0,0)
\axesIIID(2,2,1.5)(3,2.5,2.5)
\ifnum\i=0\relax\else
\defFunction[algebraic]{sphere}(u,v){2*cos(u)*cos(v)} {2*sin(u)*cos(v)} {2*sin(v)}
\psSolid[object=surfaceparametree,base=pi neg pi 0 \r,hue=0.2 0.8,function=sphere,linewidth=0.2pt,opacity=0.8,ngrid=0.1]
\fi
\end{pspicture}}
\end{document}


And the output is:

(I hope 101.54 KB does not matter)

Anthony Phan has written a 3d extension of Metapost, m3D, which extends Metapost with primitives to express surfaces, 3d affine transformations (allowing you to express paths on surfacces), and surface rendering with light sources. I gave an example generated by m3D in my answer to How to draw a torus. I think the code hasn't been worked on since 2006.

Dennis Riegel has a fairly well-used Metapost library providing 3d concepts.