3

I was really happy to see that matlab2tikz also supports surf plots. Unfortunately, it produces too much data, so I run into the well-known memory problem. I tried compiling with lualatex instead of pdflatex, but I get errors like

Package pgfkeys Error: I do not know the key '/tikz/axis lines*' and I am goi ng to ignore it. Perhaps you misspelled it.

Since I have never used lualatex before, I have not tried any further at this point, but I am open to suggestions.

I then found the option 'minimumPointsDistance' for matlab2tikz. This works great for normal plots, but it seems to have no effect for a surf plot.

I then tried the option 'each nth point' in the tikzpicture. Using every tenth point is fine for compiling, but does not produce an acceptable plot. 7 is better, but still far from ok, 6 gives me the old memory problem.

I tried doing the plot in MatLab with only half the points in each direction, but this looks worse than 'each nth point={10}'.

Why does this have to be so complicated? This was only a test run with 100 by 100 points!

There is still room for optimization, though. A large portion of my plot is close to zero, so it would be best to kick out some of those. The interesting part seems to be very sensitive to leaving out points, so I would prefer a solution that can use the whole output.

I know, I can always produce an eps file and convert it to pdf. It looks ok, especially if I set axis off in MatLab. But then I don't know how to recreate them with tikz...

I'm really running out of options now and hoping desperately for any kind of help or suggestions!

schnupsi
  • 183
  • Try plot2svg and generate svg file of your surface plot. Then open it in inkscape and export the tikz code. for details refer to this answer : http://tex.stackexchange.com/a/82315/11232 –  Dec 06 '12 at 16:24
  • 1
    exporting from svg to tikz will create the same memory problems as the number of lines to be drawn will be huge. you should either try to filter your data in matlab, or create a plot with no axes in matlab and with a defined viewport and make the graph the right size, save it as png picture and then add the axes in your socument with pgfplots – Martin H Dec 06 '12 at 16:31
  • @HarishKumar: I forgot to write that I tried that as well. I never found out about the memory issue, though, because I could not export to tikz. In inkscape, the is only the possibility to save as .tex with latex+pstricks and I do not want that. – schnupsi Dec 06 '12 at 16:36
  • @MartinH: Is png better? I thought eps and then pdf had better quality outputs... But I guess I do have to resort to one of them and will not be able to alter stuff in my plot if needed... – schnupsi Dec 06 '12 at 16:39
  • 1
    No, png would certianly not be your first choice, but a pixel graphic will render much quicker than the vector graphic. If you take care and export the graph at the correct size, so you do not need to scale it in the document, you won't be able to tell the difference though. pgfplots has this graphic feature where you can add the axes and axes ticks in text font, this is why I would export the graph only without any axes – Martin H Dec 06 '12 at 16:48
  • @schnupsi You have to install inkscape2tikz from http://code.google.com/p/inkscape2tikz/ to export it to tikz. –  Dec 06 '12 at 22:20
  • @MartinH I read about the graphic feature. You mentioned the viewport, which was actually a good clue because I only tried this once with 2 axes, so it looked really dumb with a 3d plot. But of course it should be possible to have 3 axes, so thanks. But back to the format: scaling sure is bad for the quality of png. That is why I used eps and pdf. As for the amount of work, it is not so bad because I have the conversion command in my MatLab script. I will play around with it and just decide by trial and error, which way comes out better. – schnupsi Dec 07 '12 at 08:35
  • You just need to know your textwidth from your latex document and then maybe do 85% of the textwith as width of your graph in matlab. You should be able to show the current width with \the\textwidth or you know it anyway from the margins you set. The aim is not to scale the picture at all to preserve quality. Matlab should give you all the tools for a decent export. You could get matlab2tikz and inkscape2tikz working, but both will cause the same memory issues because of the large number of points – Martin H Dec 07 '12 at 08:58
  • 1
    Well, the error with axis lines sounds a lot as if (a) lualatex succeeded in creating the plot as such (b) your pgfplots version is older than what matlab2tikz expects. In other words: your export would have failed with pdflatex as well; try updating pgfplots and then rerun the approach with lualatex. – Christian Feuersänger Dec 08 '12 at 09:32
  • @ChristianFeuersänger Thanks for your answer, but it's not pgfplots. I've had version 1.5.1 installed since june. I tried a smaller sample size of my Matlab surf plot and it worked fine with pdflatex. All my 2d plots have worked fine so far. So it really is just a memory issue here. As for lualatex, I have no clue since I have never used it before. I just tried it because in all memory size related posts people said luatalex does not have such a restriction. Maybe there are other issues that I'm not aware of. – schnupsi Dec 11 '12 at 08:34

1 Answers1

5

The error with /tikz/axis lines* indicates that your pgfplots version is very old (and matlab2tikz uses pgfplots). I'd expect the same problem for both pdflatex and lualatex. I guess that your version might even be older than version 1.3. In that case, it might not support 3d axes at all?

I think you have the following choices to proceed:

  1. downsample your data by means of matlab. Using half as many point might be too much, see interp2 in matlab.

  2. Retry with a more recent version of pgfplots and lualatex. See below for an example.

  3. Read "External Three-Dimensional Graphics and Matlab" in the pgfplots manual (if you have a recent version!). That section contains a script written by Jake in 3-dimensional histogram in pgfplots which allows to create a PNG image of your MATLAB image and a pgfplots axis easily.

If you want to follow (2), here is what I got for a custom sample:

\documentclass{standalone}

\usepackage{pgfplots}

\begin{document}

\begin{tikzpicture}
\begin{axis}[
    title=$120 \times 120$ Smooth Surface,
    xlabel=$x$,
    ylabel=$y$]
\addplot3[surf,samples=120,shader=interp,domain=0:1]
    {sin(deg(8*pi*x))* exp(-20*(y-0.5)^2)
    + exp(-(x-0.5)^2*30
        - (y-0.25)^2 - (x-0.5)*(y-0.25))};
\end{axis}
\end{tikzpicture}

\end{document}

enter image description here

the 120x120 grid resulted in a 130kb pdf file and took 2 minutes to run through lualatex on my system.

If both compilation time requirement and size limit appear to be acceptable for you, then you should ensure that matlab2tikz produces output with \addplot3[...., surf, shader=interp,...] and run it through lualatex. Otherwise you should reconsider (1.) or (3.). However, running it through lualatex should work fairly well, especially if you ensure that you avoid unnecessary successive recompilation (see external lib or standalone).

  • Thanks for this detailed answer. As I wrote above, my version of pgfplots is not too old, it's 1.5.1. I tried your above example (with \documentclass{article}, since standalone does not come with Ubuntu's Tex Live) and I get the memory problem with pdflatex and with lualatex: `Runaway argument? sin(deg(8pix))* exp(-20(y-0.5)^2) + exp(-(x-0.5)^230 - (y-0.25)^2\ETC. ! Paragraph ended before \pgfplots@addplotimpl@expression@split@yz was complete . \par l.16

    ?` So I guess I will go for your third option or stick with pdf-Files produced by Matlab.

    – schnupsi Dec 11 '12 at 09:07
  • Ok. However, your Runaway argument error is no memory issue... it sounds like a copy-paste error (perhaps some empty line has been inserted or the final semicolon is missing). Note that as far as I know, lualatex behaves in the same way as pdflatex for all common use-cases. – Christian Feuersänger Dec 11 '12 at 19:55
  • I'm using exactly your example - except for the documentclass: \documentclass{article} \usepackage{pgfplots} \begin{document} \begin{tikzpicture} \begin{axis}[title=$120 \times 120$ Smooth Surface,xlabel=$x$,ylabel=$y$] \addplot3[surf,samples=120,shader=interp,domain=0:1]{sin(deg(8*pi*x))*exp(-20*(y-0.5)^2)+exp(-(x-0.5)^2*30-(y-0.25)^2-(x-0.5)*(y-0.25))}; \end{axis} \end{tikzpicture} \end{document} If there was a syntax problem, pdflatex would have noticed, I guess. – schnupsi Dec 12 '12 at 12:12