# 3D statistical figures

I wonder which software (e.g. MetaPost, TikZ, etc.) is best to use to reproduce the figure pasted below. The example is taken from new data mining book (p. 205).

• For data mining graphs, my recommendation would be to use Asymptote, since it is a full-featured programming language and can more easily be programmed to translate data from whatever form it is given in. – Charles Staats Oct 11 '13 at 19:21
• From a purely graphical standpoint, any of the standard four (TikZ, PStricks, Metapost, and Asymptote) can almost certainly reproduce and improve the figures given. Asymptote and probably PStricks can also determine automatically which drawing features are in front of which others; this would make it easier to get the dashed lines correct (which the example diagrams do not) and to have the same axis drawn over some points but under others. – Charles Staats Oct 11 '13 at 19:25
• @CharlesStaats I do not think that Asymptote and Pstricks can automatically determine which drawing features are in front with vector formats. With Asymptote, your statement is true only for rasterized output. – pluton Oct 12 '13 at 2:16
• pgfplots is quite strong when it comes to scatter plots, especially if markers need to be colored (or styled) according to some meta data column. See pgfplots.sourceforge.net for an excerpt of the examples documented in the manual to see if it fits your needs. The associated sourcecode of all such examples can be found in pgfplots.sourceforge.net/gallery.html or in the manual directly. – Christian Feuersänger Oct 12 '13 at 11:44

This is the picture for the Original Basis, made with the Asymptote in vector format.

% iris3d.tex :
%
%% database iris.data from
%% http://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data
%
\begin{filecontents*}{iris.data}
5.1,3.5,1.4,0.2,Iris-setosa
4.9,3.0,1.4,0.2,Iris-setosa
4.7,3.2,1.3,0.2,Iris-setosa
4.6,3.1,1.5,0.2,Iris-setosa
5.0,3.6,1.4,0.2,Iris-setosa
5.4,3.9,1.7,0.4,Iris-setosa
4.6,3.4,1.4,0.3,Iris-setosa
5.0,3.4,1.5,0.2,Iris-setosa
4.4,2.9,1.4,0.2,Iris-setosa
4.9,3.1,1.5,0.1,Iris-setosa
5.4,3.7,1.5,0.2,Iris-setosa
4.8,3.4,1.6,0.2,Iris-setosa
4.8,3.0,1.4,0.1,Iris-setosa
4.3,3.0,1.1,0.1,Iris-setosa
5.8,4.0,1.2,0.2,Iris-setosa
5.7,4.4,1.5,0.4,Iris-setosa
5.4,3.9,1.3,0.4,Iris-setosa
5.1,3.5,1.4,0.3,Iris-setosa
5.7,3.8,1.7,0.3,Iris-setosa
5.1,3.8,1.5,0.3,Iris-setosa
5.4,3.4,1.7,0.2,Iris-setosa
5.1,3.7,1.5,0.4,Iris-setosa
4.6,3.6,1.0,0.2,Iris-setosa
5.1,3.3,1.7,0.5,Iris-setosa
4.8,3.4,1.9,0.2,Iris-setosa
5.0,3.0,1.6,0.2,Iris-setosa
5.0,3.4,1.6,0.4,Iris-setosa
5.2,3.5,1.5,0.2,Iris-setosa
5.2,3.4,1.4,0.2,Iris-setosa
4.7,3.2,1.6,0.2,Iris-setosa
4.8,3.1,1.6,0.2,Iris-setosa
5.4,3.4,1.5,0.4,Iris-setosa
5.2,4.1,1.5,0.1,Iris-setosa
5.5,4.2,1.4,0.2,Iris-setosa
4.9,3.1,1.5,0.1,Iris-setosa
5.0,3.2,1.2,0.2,Iris-setosa
5.5,3.5,1.3,0.2,Iris-setosa
4.9,3.1,1.5,0.1,Iris-setosa
4.4,3.0,1.3,0.2,Iris-setosa
5.1,3.4,1.5,0.2,Iris-setosa
5.0,3.5,1.3,0.3,Iris-setosa
4.5,2.3,1.3,0.3,Iris-setosa
4.4,3.2,1.3,0.2,Iris-setosa
5.0,3.5,1.6,0.6,Iris-setosa
5.1,3.8,1.9,0.4,Iris-setosa
4.8,3.0,1.4,0.3,Iris-setosa
5.1,3.8,1.6,0.2,Iris-setosa
4.6,3.2,1.4,0.2,Iris-setosa
5.3,3.7,1.5,0.2,Iris-setosa
5.0,3.3,1.4,0.2,Iris-setosa
7.0,3.2,4.7,1.4,Iris-versicolor
6.4,3.2,4.5,1.5,Iris-versicolor
6.9,3.1,4.9,1.5,Iris-versicolor
5.5,2.3,4.0,1.3,Iris-versicolor
6.5,2.8,4.6,1.5,Iris-versicolor
5.7,2.8,4.5,1.3,Iris-versicolor
6.3,3.3,4.7,1.6,Iris-versicolor
4.9,2.4,3.3,1.0,Iris-versicolor
6.6,2.9,4.6,1.3,Iris-versicolor
5.2,2.7,3.9,1.4,Iris-versicolor
5.0,2.0,3.5,1.0,Iris-versicolor
5.9,3.0,4.2,1.5,Iris-versicolor
6.0,2.2,4.0,1.0,Iris-versicolor
6.1,2.9,4.7,1.4,Iris-versicolor
5.6,2.9,3.6,1.3,Iris-versicolor
6.7,3.1,4.4,1.4,Iris-versicolor
5.6,3.0,4.5,1.5,Iris-versicolor
5.8,2.7,4.1,1.0,Iris-versicolor
6.2,2.2,4.5,1.5,Iris-versicolor
5.6,2.5,3.9,1.1,Iris-versicolor
5.9,3.2,4.8,1.8,Iris-versicolor
6.1,2.8,4.0,1.3,Iris-versicolor
6.3,2.5,4.9,1.5,Iris-versicolor
6.1,2.8,4.7,1.2,Iris-versicolor
6.4,2.9,4.3,1.3,Iris-versicolor
6.6,3.0,4.4,1.4,Iris-versicolor
6.8,2.8,4.8,1.4,Iris-versicolor
6.7,3.0,5.0,1.7,Iris-versicolor
6.0,2.9,4.5,1.5,Iris-versicolor
5.7,2.6,3.5,1.0,Iris-versicolor
5.5,2.4,3.8,1.1,Iris-versicolor
5.5,2.4,3.7,1.0,Iris-versicolor
5.8,2.7,3.9,1.2,Iris-versicolor
6.0,2.7,5.1,1.6,Iris-versicolor
5.4,3.0,4.5,1.5,Iris-versicolor
6.0,3.4,4.5,1.6,Iris-versicolor
6.7,3.1,4.7,1.5,Iris-versicolor
6.3,2.3,4.4,1.3,Iris-versicolor
5.6,3.0,4.1,1.3,Iris-versicolor
5.5,2.5,4.0,1.3,Iris-versicolor
5.5,2.6,4.4,1.2,Iris-versicolor
6.1,3.0,4.6,1.4,Iris-versicolor
5.8,2.6,4.0,1.2,Iris-versicolor
5.0,2.3,3.3,1.0,Iris-versicolor
5.6,2.7,4.2,1.3,Iris-versicolor
5.7,3.0,4.2,1.2,Iris-versicolor
5.7,2.9,4.2,1.3,Iris-versicolor
6.2,2.9,4.3,1.3,Iris-versicolor
5.1,2.5,3.0,1.1,Iris-versicolor
5.7,2.8,4.1,1.3,Iris-versicolor
6.3,3.3,6.0,2.5,Iris-virginica
5.8,2.7,5.1,1.9,Iris-virginica
7.1,3.0,5.9,2.1,Iris-virginica
6.3,2.9,5.6,1.8,Iris-virginica
6.5,3.0,5.8,2.2,Iris-virginica
7.6,3.0,6.6,2.1,Iris-virginica
4.9,2.5,4.5,1.7,Iris-virginica
7.3,2.9,6.3,1.8,Iris-virginica
6.7,2.5,5.8,1.8,Iris-virginica
7.2,3.6,6.1,2.5,Iris-virginica
6.5,3.2,5.1,2.0,Iris-virginica
6.4,2.7,5.3,1.9,Iris-virginica
6.8,3.0,5.5,2.1,Iris-virginica
5.7,2.5,5.0,2.0,Iris-virginica
5.8,2.8,5.1,2.4,Iris-virginica
6.4,3.2,5.3,2.3,Iris-virginica
6.5,3.0,5.5,1.8,Iris-virginica
7.7,3.8,6.7,2.2,Iris-virginica
7.7,2.6,6.9,2.3,Iris-virginica
6.0,2.2,5.0,1.5,Iris-virginica
6.9,3.2,5.7,2.3,Iris-virginica
5.6,2.8,4.9,2.0,Iris-virginica
7.7,2.8,6.7,2.0,Iris-virginica
6.3,2.7,4.9,1.8,Iris-virginica
6.7,3.3,5.7,2.1,Iris-virginica
7.2,3.2,6.0,1.8,Iris-virginica
6.2,2.8,4.8,1.8,Iris-virginica
6.1,3.0,4.9,1.8,Iris-virginica
6.4,2.8,5.6,2.1,Iris-virginica
7.2,3.0,5.8,1.6,Iris-virginica
7.4,2.8,6.1,1.9,Iris-virginica
7.9,3.8,6.4,2.0,Iris-virginica
6.4,2.8,5.6,2.2,Iris-virginica
6.3,2.8,5.1,1.5,Iris-virginica
6.1,2.6,5.6,1.4,Iris-virginica
7.7,3.0,6.1,2.3,Iris-virginica
6.3,3.4,5.6,2.4,Iris-virginica
6.4,3.1,5.5,1.8,Iris-virginica
6.0,3.0,4.8,1.8,Iris-virginica
6.9,3.1,5.4,2.1,Iris-virginica
6.7,3.1,5.6,2.4,Iris-virginica
6.9,3.1,5.1,2.3,Iris-virginica
5.8,2.7,5.1,1.9,Iris-virginica
6.8,3.2,5.9,2.3,Iris-virginica
6.7,3.3,5.7,2.5,Iris-virginica
6.7,3.0,5.2,2.3,Iris-virginica
6.3,2.5,5.0,1.9,Iris-virginica
6.5,3.0,5.2,2.0,Iris-virginica
6.2,3.4,5.4,2.3,Iris-virginica
5.9,3.0,5.1,1.8,Iris-virginica
\end{filecontents*}
\documentclass{article}
\usepackage[inline]{asymptote}
\usepackage{lmodern}
\begin{document}
\begin{figure}
\begin{asy}
settings.outformat="pdf";
settings.tex="pdflatex";
settings.prc=false;
settings.render=0;

size(8cm);
import solids;
import fontsize;
defaultpen(fontsize(9pt));

pen axisPen=darkblue+1bp;
pen frameSolid=gray(0.5)+1bp;
pen frameDashed=frameSolid+linetype(new real[] {3,2});
pen dotRim=gray(0.17);

pen[] clr={white
,mediumred   + opacity(0.5)
,mediumgreen + opacity(0.5)
,mediumblue  + opacity(0.5)
};

path dotMark=scale(0.08)*unitcircle;

triple eyeVec;
triple plane(pair z);

file fin=input("iris.data").csv();
string[][] A=fin.dimension(0,5);

triple[] p;
int[] IrisType;
int[] zIndex;

triple pmin=(1,1,1)*intMax,pmax=-pmin;

bool less(int i, int j){
return arclength(p[i]--currentprojection.camera)
>arclength(p[j]--currentprojection.camera);
}

void calcZindex(){
zIndex=sort(sequence(p.length),less);
}

void Dot(triple q,pen c){
triple u, v;
v=Z;
u=unit(cross(eyeVec,v));
plane=new triple (pair z) {return q+z.x*u+z.y*v;};
draw(surface(dotMark,plane),c,nolight);
draw((shift(q)*rotate(90,u)*path3(dotMark)),dotRim,nolight);
}

for(int i=0;i<A.length;++i){
if(A[i].length==5){
p.push(((real)A[i][0],(real)A[i][1],(real)A[i][2]));
if(p[i].x<pmin.x)pmin=(p[i].x,pmin.y,pmin.z);
if(p[i].y<pmin.y)pmin=(pmin.x,p[i].y,pmin.z);
if(p[i].z<pmin.z)pmin=(pmin.x,pmin.y,p[i].z);
if(p[i].x>pmax.x)pmax=(p[i].x,pmax.y,pmax.z);
if(p[i].y>pmax.y)pmax=(pmax.x,p[i].y,pmax.z);
if(p[i].z>pmax.z)pmax=(pmax.x,pmax.y,p[i].z);
IrisType.push(0);
if(A[i][4]=="Iris-setosa")IrisType[i]=1;
if(A[i][4]=="Iris-versicolor")IrisType[i]=2;
if(A[i][4]=="Iris-virginica")IrisType[i]=3;
}
}

currentprojection=orthographic(
camera=(12,10,0.4),
up=Z,
target=(pmin+pmax)/2,
zoom=0.8
);

eyeVec=currentprojection.camera-currentprojection.target;

calcZindex();

triple pmid=0.5(pmin+pmax);

draw((pmin.x,pmid.y,pmid.z)--(pmax.x,pmid.y,pmid.z)
label("$X_1$",project((pmax.x,pmid.y,pmid.z)),W);

draw((pmid.x,pmin.y,pmid.z)--(pmid.x,pmax.y,pmid.z)
label("$X_2$",project((pmid.x,pmax.y,pmid.z)),E);

draw((pmid.x,pmid.y,pmin.z)--(pmid.x,pmid.y,pmax.z)
label("$X_3$",project((pmid.x,pmid.y,pmax.z)),N);

draw(pmin--(pmin.x,pmax.y,pmin.z)--(pmin.x,pmin.y,pmin.z)--(pmax.x,pmin.y,pmin.z)--cycle
,frameDashed
);

draw((pmax.x,pmax.y,pmin.z)--pmax,frameDashed);
draw((pmax.x,pmin.y,pmin.z)--(pmax.x,pmax.y,pmin.z)--(pmin.x,pmax.y,pmin.z),frameDashed);

for(int i=0;i<p.length;++i){
Dot(p[zIndex[i]],clr[IrisType[zIndex[i]]]);
}

draw(pmax--(pmin.x,pmax.y,pmax.z)--(pmin.x,pmin.y,pmax.z)--(pmax.x,pmin.y,pmax.z)--cycle
,frameSolid
);

draw((pmax.x,pmin.y,pmin.z)--pmin--(pmin.x,pmax.y,pmin.z),frameSolid);
draw((pmin.x,pmin.y,pmax.z)--pmin,frameSolid);
draw((pmin.x,pmax.y,pmax.z)--(pmin.x,pmax.y,pmin.z),frameSolid);
draw((pmax.x,pmin.y,pmax.z)--(pmax.x,pmin.y,pmin.z),frameSolid);
\end{asy}
\end{figure}
\end{document}
%
% Process with:
%
% pdflatex iris3d.tex
% asy iris3d-*.asy
% pdflatex iris3d.tex

• It looks to my eyes as if all of the balls are the same radius. – Benjamin McKay Oct 12 '13 at 14:50
• @Benjamin McKay: Yes, they are. Why? – g.kov Oct 12 '13 at 15:06