12

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 picutre. I used the following code for it:

\begin{tikzpicture}
 \begin{axis}[view={0}{90},colormap/cool]
  \addplot3[surf] table [row sep=newline] {./workfile.dat};
 \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)?

4
  • 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. Commented Mar 30, 2012 at 15:04
  • that will be no problem with PSTricks: tug.org/PSTricks/main.cgi?file=pst-plot/3D/contour
    – user2478
    Commented Mar 30, 2012 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
    Commented Mar 30, 2012 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
    Commented Mar 30, 2012 at 15:57

1 Answer 1

13

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]
\addplot graphics [xmin=0,xmax=87,ymin=0,ymax=61] {volcano.png};
\end{axis}
\end{tikzpicture}
\end{document}
3
  • 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
    Commented Sep 20, 2012 at 13:12
  • @Vegard: I tried with a simple 2x2 matrix, and that is plotted correctly. Could you post a new question with an example where you see that behaviour?
    – Jake
    Commented Sep 21, 2012 at 6:19
  • I posted my question here: tex.stackexchange.com/questions/73640/… However, I found one answer/workaround myself. Thanks.
    – Vegard
    Commented Sep 22, 2012 at 14:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .