6

I am searching for the best way, software or script (latex, python, R, octave), to interactively draw or paint some 3D surface plot for pedagogic usage.

I finally found a way to generate and transform pdf 3D surface plot with svg export using pgfplots latex package. Thus I can redraw/rework initial drawing to render a graphic like this.

pedagogic surface

But I don't want to use a common mathematic function for input of the 3d drawing, I want to use, if possible, a heightmap to generate the surface.

enter image description here

Is it possible to transform a random black and white heightmap into a 3Dsurface plot with pgfplots ?

12

I used scipy to transform the heightmap to a data matrix and then wrote the coordinates and the height values to a file.

Exact height profile

#!/usr/bin/python

import numpy as np
from scipy import misc

matrix = misc.imread('536ws.jpg',flatten=True)
x,y = matrix.shape

mesh = ""
for i in range(0,x):
    for j in range(0,y):
        mesh += "%d\t%d\t%d\n" % (i,j,matrix[i,j])
    mesh += "\n"

print mesh

I ran the script and piped the output to a file called matrix.dat

python extract.py > matrix.dat

Then I used pgfplots to visualise the matrix

\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\begin{document}
\begin{tikzpicture}
  \begin{axis}
    \addplot3[surf,colormap/blackwhite,mesh/ordering=y varies] table {matrix.dat};
  \end{axis}
\end{tikzpicture}
\end{document}

You need to use lualatex for this as pdflatex will run out of memory. Processing this file takes ca. 1 minute and 52 seconds on my machine.

In the rendered png the colour map turned out darker than in the pdf.

enter image description here

Averaged height profile

The following script introduces some averaging over all points of the mesh (factor of 5 here). The rest of the procedure stays the same.

#!/usr/bin/python

import numpy as np
from scipy import misc

matrix = misc.imread('536ws.jpg',flatten=True)
x,y = matrix.shape
matrix = misc.imresize(matrix,(x/5,y/5))
x,y = matrix.shape

mesh = ""
for i in range(0,x):
    for j in range(0,y):
        mesh += "%d\t%d\t%d\n" % (i,j,matrix[i,j])
    mesh += "\n"

print mesh

This is now compilable with pdflatex (no more out-of-memory) and takes ca. 3 seconds.

enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.