Plot Surface from Data – How to Use pgfplots and Asymptote

3dasymptotepgfplotswolfram-mathematica

Disclaimer: I already read questions like 2D surface on a 3D surface plot external data in a file and 3D surface plots in TikZ but these did not solve my problem.

I have this set of data:

x       y       z
2.17    0.001   0.82044815
2.17    0.002   0.82345825
2.17    0.004   0.82679255
2.17    0.008   0.83334715
2.17    0.016   0.84395915
2.17    0.032   0.8584953
2.21    0.001   0.77582165
2.21    0.003   0.78520505
2.21    0.009   0.80205985
2.21    0.027   0.83085105
2.24    0.001   0.7227885
2.24    0.002   0.73391615
2.24    0.005   0.7543979
2.24    0.015   0.78798745
2.24    0.003   0.74176635
2.24    0.009   0.77064805
2.24    0.027   0.81042375
2.26    0.001   0.66545585
2.26    0.003   0.7012046
2.26    0.005   0.721067
2.26    0.009   0.7447984
2.26    0.015   0.76715245
2.26    0.027   0.794177
2.27    0.001   0.62916195
2.27    0.003   0.6774642
2.27    0.009   0.72961785
2.27    0.027   0.7861086
2.28    0.001   0.5750828
2.28    0.003   0.65059675
2.28    0.005   0.6802631
2.28    0.009   0.7145367
2.28    0.015   0.74447695
2.28    0.027   0.7774403
2.29    0.001   0.51357255
2.29    0.002   0.581053
2.29    0.003   0.6173075
2.29    0.009   0.6972096
2.29    0.027   0.76793225
2.31    0.001   0.36997965
2.31    0.002   0.474415
2.31    0.003   0.53649295
2.31    0.009   0.6587164
2.31    0.016   0.70870255
2.31    0.027   0.7482423
2.31    0.05    0.7912395
2.34    0.001   0.2204104
2.34    0.002   0.316308
2.34    0.003   0.39256745
2.34    0.004   0.45240835
2.34    0.009   0.5883453
2.34    0.016   0.6590771
2.34    0.027   0.71444205
2.34    0.05    0.7690014
2.38    0.001   0.13286995
2.38    0.002   0.1828288
2.38    0.004   0.2980268
2.38    0.008   0.4507145
2.38    0.016   0.58417075
2.38    0.032   0.6833616

And if I plot it in Mathematica (with ListPlot3D[data]) it looks, without further tweaking and fiddling around, like:

enter image description here

But if I try this pgfplots code

\begin{tikzpicture}
  \begin{axis}
    \addplot3 [surf] table {data.txt};
  \end{axis}
\end{tikzpicture}

I only get this:

enter image description here

What do I have to do to get a surface like in Mathematica (color, smoothness, style, etc. does not matter, just a closed surface)?

Best Answer

If you have octave installed, you can triangulate the data from within your LaTeX document using the \addplot shell functionality and plot it using the patch plot style.

\documentclass[border= 5mm]{standalone}
\usepackage{pgfplots}

\begin{document}
    \begin{tikzpicture}
    \begin{axis}
        \addplot3 [patch, patch table={triangles.txt}
   ] shell {echo "data=dlmread('data.txt');
    tri=delaunay(data(:,1), data(:,2));
    dlmwrite('triangles.txt',tri-1,' ');
    disp(data)" | octave --silent};
    \end{axis}
    \end{tikzpicture}
\end{document}

You can also grid the data:

\documentclass[border= 5mm]{standalone}
\usepackage{pgfplots}

\begin{document}
    \begin{tikzpicture}
    \begin{axis}
    \addplot3 [surf, mesh/cols=50, z buffer=sort, restrict z to domain=0:inf, shader=faceted interp] shell {
    echo "
        data=dlmread('data.txt');
        res=\pgfkeysvalueof{/pgfplots/mesh/cols};
        [xx,yy] = meshgrid(linspace(min(data(:,1)), max(data(:,1)),res), linspace(min(data(:,2)), max(data(:,2)),res));
        zz=griddata(data(:,1),data(:,2),data(:,3),xx,yy);
        zz(isnan(zz))=-999;
        disp([xx(:) yy(:) zz(:)])
    " | octave --silent};   
    \addplot3 [only marks] file {data.txt};
    \end{axis}
    \end{tikzpicture}
\end{document}

Gnuplot could be used to interpolate scattered data, but the available interpolation functions don't work particularly well for this dataset.

\documentclass[border= 5mm]{standalone}
\usepackage{pgfplots}

\begin{document}
    \begin{tikzpicture}
    \begin{axis}
    \addplot3 [surf] gnuplot [raw gnuplot] {
        set dgrid3d 30,30 spline;
        splot 'data.txt';       
    };
    \addplot3 [only marks] table {data.txt};
    \end{axis}
    \end{tikzpicture}
\end{document}
Related Question