# generate a surf plot from a text file

I would like to create a surf plot (like mesh in Matlab) with a view from the top. From a bit leasing I found this way for accomplishing that:

\begin{tikzpicture}
\begin{axis}{view={0}{90}]
\appplot3[surf] table {datafile.dat};
\end{axis}
\end{tikzpicture}


At the moment my data, that I would like to plot, is a 400 x 1000 matrix, where the values in the matrix represent the hight (or color).

In which format do I need to generate datafile.dat, so that \addplot3[surf] could read it?

I found few formats:

(x value, y value, z value)
(x value, y value)[ z value]


The easy way for me would be if I could simply generate a matrix with the size 400 x 1000, which contains the z values, and in addition to scale the values of the x-axis and y-axis.

EDIT

I generated a file at the format Jake gave. As jake said, using pdflatex returned TeX capacity exceeded, sorry [main memory size=3000000], but from the other side, lualatex returned

! Package pgfplots Error: Could not read table file '/tmp/workfile'. In case yo
u intended to provide inline data: maybe TeX screwed up your end-of-lines? Try
row sep=crcr' and terminate your lines with \\' (refer to the pgfplotstable m
anual for details).


which was not experted.

EDIT 2

I was able to create the following . I used the following code for it:

\begin{tikzpicture}
\begin{axis}[view={0}{90},colormap/cool]
\end{axis}
\end{tikzpicture}


I would like that for value to have the color white and in my picture, about 90% of the values are null, but in the picture it is not the case (there is some kind of hell blue). How could it be fixed?

Is it also possible to consider only values which are bigger then a specific value?

In python matplotlib there is a possibility to use a LogNorm scale for the colors. Is it also possible in tikz (in this case)?

-
Data files at such a fine resolution are currently beyond the capabilities of pgfplots. Aside from the translation time, the pdf gets huge. It gets a little better with the suggestion of Jake in his answer, and shader=interp also reduces both translation time + pdf size + looks better for such resolutions. You may, however, want to consider generating a png graphics with (say) matlab and overlay a pgfplots axis with \addplot graphics. This reduces both typesetting time + pdf size. –  Christian Feuersänger Mar 30 '12 at 15:04
that will be no problem with PSTricks: tug.org/PSTricks/main.cgi?file=pst-plot/3D/contour –  Herbert Mar 30 '12 at 15:16
the problem was solved by changing the file name from '/tmp/workfile' to '/tmp/workfile.dat'. I will try later 'shader=interp'. What i have not understand is \addplot graphics, am i suppose to write graphics instead of table? –  Eagle Mar 30 '12 at 15:36
@Eagle: I've edited my answer to include an example of how to use \addplot graphics to use an external image in the plot. This is a very sensible approach for applications like this, since there's nothing to be gained from having a vector version of a gridded plot, quite contrary: As the PDF Herbert linked to demonstrates, vector versions of such plots become very large and unwieldy. –  Jake Mar 30 '12 at 15:57

The preferred format is

<x1> <y1> <z>
<x1> <y2> <z>
<x1> <y3> <z>

<x2> <y1> <z>
<x2> <y2> <z>
<x2> <y3> <z>


i.e. blocks of rows of coordinates with identical x or y values, separated by a blank line. If you omit the blank lines, you'll have to tell PGFplots how many rows or columns you have in your grid.

Here's an example of the volcano dataset that ships with R. I used

library(reshape)
data(volcano)
molten <- melt(volcano)
write.table(molten, row.names=F, "volcano.dat")


to turn the matrix structure into a list of coordinates. The first ten lines then look like

1 1 100
2 1 101
3 1 102
4 1 103
5 1 104
6 1 105
7 1 105
8 1 106
9 1 107
10 1 108


This can then be plotted with PGFplots. Note, however, that this is a very memory intensive task, even the 87 by 61 volcano dataset could only be plotted using lualatex because pdflatex would exceed its memory limits. Plotting a 400 by 1000 matrix would take a very long time.

You might be better off generating the plot image in an external program like R and then using PGFplots to add the axes and labels.

Here's an example of generating a heatmap of the volcano dataset using R, without margins or axes:

data(volcano)
png("volcano.png")
par(mar=c(0,0,0,0))
image(volcano,col=terrain.colors(50),axes=F)
dev.off()


This can then be used in a PGFPlots plot using

\documentclass{article}

\usepackage{pgfplots}

\begin{document}
\begin{tikzpicture}
\begin{axis}[enlargelimits=false, axis on top]

In my experience, the pure-pgfplots solution chops off the last row and the last column. Any idea how to fix that? (It's not a problem with xmax/ymax; if I increase them, nothing is drawn in the last row/column.) –  Vegard Sep 20 '12 at 13:12