# MATLAB 5 plots under Linux

How Pstoedit, Tgif, LaTeX and A2ps can get along with MATLAB figures

Marco De la Cruz-Heredia
[marco@atmosp.physics.utoronto.ca]



New! Contribute MATLAB [benchmarks]!

## Introduction

 Hello Web-surfer! My name is Chibi Top and I'm a MATLAB hacker and Linux nut! Today I'll be sharing a few tips on how to get the most out of your MATLAB plots using a bunch of Linux tools and utilities! By the end of this session you will know how to make the figure shown below and include it in a LaTeX document. Is that cool or what!?

(Click on it!)

 Before we start, remember: the most important MATLAB command is "help"! That is, typing "help plot" will give you lots of useful information about the "plot" command. Not sure what the name of the command is? Try "lookfor", which searches all m-file comments. Frustrated because "5!" and "fact(5)" don't work? Just type:
>> lookfor factorial -all
GALLERY Higham test matrices.
FACTORIAL Factorial function.
GAMMA  Gamma function.
IPJFACT Hankel matrix with factorial elements.


Now you're cooking! (^-^)

## Step 1: Making a pseudocolor plot

I will start by making a checkerboard plot. The commands:

PeaksCPlotHandle = axes('Position',[.1 .1 .75 .8],'Visible','off');

% Make the contour plot
pcolor(peaks)

colormap(1 - 0.7*hot)

set(PeaksCPlotHandle,'XTickLabel',[])
set(PeaksCPlotHandle,'YTickLabel',[])

title({'Using cells','we have two rows!'},'Rotation',0)
xlabel('x')
ylabel('y','Rotation',0,'FontSize',16)

 will create a set of axes (called "PeaksCPlotHandle") which contain the shaded contour plot generated by the "pcolor" command. I set the "shading" to "flat" and made a cool "colormap". Note that I modified one of the built-in colour scheme through a few simple operations. Multiplying it by some number changes the brightness, while subtracting from one makes a negative image so that the high regions are dark. A list of colour maps can be obtained by typing "help graph3d". The next two lines clear the tick labels and then the next three add a title and labels to the axes. Note how we can change font properties from within the "?label" commands. Note too that labels and titles can have more than one row by using strings within cells. Tags must be be horizontal, otherwise Tgif will be unable to read them. (LaTeX can rotate them for us later). The figure so far looks like this:

## Step 2: Adding contours and using "clabel"

Although the shading indicates regions of high and low values it isn't very quantitative. I'll fix this by adding contours:

hold on
ContourHandle = contour(peaks,'b--');
clabel(ContourHandle,'FontSize',15,'Color','r','Rotation',0)

 Note that I must first "hold" the plot in order to overlap the contour lines. Furthermore, the "clabel" function used here is the one created by fellow hacker [R Pawlowicz], although I think it's currently bundled with MATLAB (if not, see [below]). Again, font properties can be easily changed within the "clabel" command. The figure is now:

## Step 3: Pointing out things with "arrow"

I shall now add an arrow and tags to indicate an interesting region :)

Here are the commands I used:
AChibi = arrow([44 32],[45 25],'ends','start');
arrow(AChibi,'FaceColor','g','EdgeColor','k','tipangle',10,'width',1)
text(43,23,'Chibi!','Color','k','FontName','utopia','FontSize',14')

 As you can see the "arrow" function is pretty nifty. It was made by [Erik A. Johnson], another fellow hacker. This function can also be found amongst the files at the [end] of this document. Note that MATLAB allows to choose from various fonts, although not all may be available on your system. For a complete listing of fonts you can type "uisetfont" at the MATLAB prompt, and then you can get the following font selector thingy...

 Hmph! Most fonts are mapped to Courier when the figure is translated and imported into Tgif, but that doesn't mean we can't make jpegs directly from MATLAB (using "print -djpeg figurename.jpg"), or later change the fonts using Tgif or (La)TeX, as seen below...

## Step 4: Making cross-sections and 2-d plots

It would be nice to see what a cross-section of the plot looks like! It's a good idea, though, to first mark where I'm making the cross-section (two, in this case):

cutx = 20;
cuty = 10;
peakdata = peaks;
plot(cutx*ones(1,length(peakdata)),[1:length(peakdata)],'y')
plot([1:length(peakdata)],cuty*ones(1,length(peakdata)),'r')


OK, now it's time to make the plot. First we have to tell MATLAB where we want the new set of axes and the size of the area they must occupy:

RightAxesHandle = axes('Position',[.855 .1 .12 .8]);

 Tip: if all your plots are of the same size you can use the command "subplot" and be done with it! Another thing is that you can break lines in MATLAB using three dots (...) as shown below. Let's plot the cuts! (But not cut the plots! OK, OK - that was lame ^_^;)
[RightAxesHandle, CutXHandle, CutYHandle] = ...
plotyy(peakdata(:,cutx),[1:length(peakdata)], ...
peakdata(cuty,:),[1:length(peakdata)]);

set(CutXHandle,'Color','y')
set(CutYHandle,'Color','r')
set(RightAxesHandle(1),'YTick',[],'YTickLabel',[],'YColor','y')
set(RightAxesHandle(2),'YTick',[10 30 40],'YTickLabel', ...
['a'; 'b'; 'c'],'YColor','r')
set(RightAxesHandle(1),'XTick',[],'XTickLabel',[])
set(RightAxesHandle(2),'XTick',[],'XTickLabel',[])

title('\Gamma_0')

 The "plotyy" command simply draws a red line where the cut along x is made, while the yellow line indicates the cut along y. Note that two vertical axes are created (that's why it's called "plotyy", duh!). The "set" commands just change the settings of the axes a bit so that they look cool. Note that (La)TeX notation can be used to adds symbols and simple equations anywhere in the figures! (Try "help text" for more info on that).

## Step 5: Adding the third set of axes and a surface plot; printing

 In order to obtain a full 3-d view of the data I will make a third set of axes and plot a surface. By now you should know the drill!
PeaksPlotHandle = axes('Position',[.1 .65 .25 .25],'Visible','off');

surf(peaks)

set(PeaksPlotHandle,'Box','on')
set(PeaksPlotHandle,'XTick',[])
set(PeaksPlotHandle,'XTickLabel',[])
set(PeaksPlotHandle,'YTick',[])
set(PeaksPlotHandle,'YTickLabel',[])
set(PeaksPlotHandle,'ZTick',[])
set(PeaksPlotHandle,'ZTickLabel',[])

 Unfortunately you can't combine two colormaps in a single figure, which is très uncool, because I wanted a surface plot with a different colour scheme. In order to do that little trick you need the Image Processing Toolbox and the "ind2rgb"/"subimage" commands. Don't ask me how, though... (try "help")

Let's print the sucker!

print -dpsc2 coolplot.ps

If you don't need to do any more image processing you can skip down to Step 8 below. Otherwise, read on...

## Step 6: Using Pstoedit

 Now, you may have noticed that the arrow in the plot points inconspicuously to me! Where is cute Chibi-chan? Well, it turns out that my picture was made using Tgif, a really cool drawing program. Pasting the pic into the plot is one way of putting it in its place, but that would probably require making bitmap images of both the plot and Chibi Top. One would like to keep everything in a nice vector format so as not to lose resolution. One way of doing this is to convert the PS plot into something [William Cheng's] Tgif understands. In order to do this one needs two programs: Ghostscript (which usually comes with Linux), and Pstoedit, a very nifty utility that allows one to covert PS files into a variety of formats including, you guessed it, Tgif object files. For starters then, let's see what Pstoedit has to say:
[snowflake]~/> pstoedit -help
pstoedit: version 3.10 (build Mar 20 1999) : Copyright (C) 1993 - 1999
Wolfgang Glunz
usage: pstoedit [-v] [-help] [-split] [-page nn] [-dt] [-merge] [-df
fontname] [-scale nn] [-dis] [-nomaptoisolatin1] [-nq] [-nb] [-flat nn]
[-bo] [-psarg string] [-include file] -f format [infile [outfile]]
Default interpreter is /usr/bin/gs
Available formats :
gnuplot:        gnuplot format
idraw:          Interviews draw format
fig:            .fig format for xfig
xfig:           .fig format for xfig
tgif:           Tgif .obj format (for tgif version >= 3)
sample:         sample driver: if you don't want to see this,
uncomment the corresponding line in makefile and make again
tk:             tk and/or tk applet source code
hpgl:           HPGL code
pic:            PIC format for troff et.al.
kil:            .kil format for KIllustrator
java:           java applet source code
rpl:            Real3D Programming Language Format
rib:            RenderMan Interface Bytestream
lwo:            LightWave 3D Object Format
psf:            Flattened PostScript (no curves)
ps:             PostScript
debug:          for test purposes
dump:           for test purposes (same as debug)
gs:             any device that GhostScript provides - use
gs:format, e.g. gs:pdfwrite
ps2ai:          Adobe Illustrator via ps2ai.ps of GhostScript


Here is the result of running it:

[snowflake]~/> pstoedit -f tgif coolplot.ps coolplot.obj
pstoedit: version 3.10 (build Mar 20 1999) :
Copyright (C) 1993 - 1999 Wolfgang Glunz
Interpreter finished. Return status 0

 Is the conversion perfect? Not always, but it's usually quite good. In particular I've noticed that fancy or rotated text doesn't translate well (if at all). In that case I'd suggest making all the MATLAB labels as simple as possible and let LaTeX do the fancy stuff (or if you use Wordperfect or something like that you can do quite a bit of text editing using Tgif, but it's not really the best tool). Dashed lines become solid, but again, Tgif can easily take care of that.
 One tricky thing sometimes is to get Pstoedit and Ghostscript working together well. It seems that every time one of the packages is upgraded they no longer like each other. The good news is that [Wolfgang Glunz], the author of Pstoedit, is a really cool guy, and he's very helpful when it comes to fixing the little boo-boos that pop up...

## Step 7: Using Tgif

 OK, so now I can load coolplot.obj into Tgif! Just type "tgif coolplot.obj &" and watch the magic take place! Ooooooooh! You may notice that when you click on things a bunch of black squares show up, usually along curves and lines. Don't worry about 'em, they are just handles which allows one to modify the various objects which make up the figure. You can just group the objects together if you like ("Ctrl-g"). The nice thing, of course, is that this is now a vector drawing (which you can edit), not a bitmap. Anyway, time to add Chibi-chan! Yay!

 After putting all together I suggest grouping the entire plot and saving it (as a Tgif object file, of course). You can now print it into an EPS file which LaTeX can read, just make sure that the menu bar at the top says LaTeX (EPS) (other formats are raw PostScript, X11 bitmap, ASCII, EPSI, PNG, HTML, PDF or the specified printer device). It is usually a good idea to select the object one wants to print and then choose -PrintSelectedObjs- from the -File- menu in order to avoid extra whitespace around the figure. IMPORTANT! Under the -File- menu make sure that you choose -Print/ExportInColor- ! Otherwise you'll get a black rectangle when you print the EPS file (this applies only to figures with colour).

## Step 8: Putting the figure inside a LaTeX document

 The final step now is to incorporate the figure into a LaTeX document. The following code readily does this:
\documentclass[12pt,titlepage]{article}

\usepackage{psfrag}
\usepackage{graphicx}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}

\begin{document}

\begin{figure}[!htbp]
\begin{center}
\psfrag{x}[ct][][1][0]{$3 (1-x)^2 e^{-x^2 - (y+1)^2} - 10 (\frac{x}{5} - x^3 - y^5) e^{-x^2-y^2} - \frac{1}{3} e^{-(x+1)^2 - y^2}$}
\psfrag{Chibi!}[][][1][0]{$\mathfrak{Chibi!}$}
\psfrag{y}[][][1][90]{y}
\includegraphics[scale = 0.9]{ChibiTop_coolplot.eps}
\end{center}
\caption{The final plot! Note that the x'' label has been
substituted for the expression of the peaks'' function,
while y'' has been rotated and Chibi!'' is now written
in a funky font...}
\end{figure}

\end{document}

 Notice that using the "psfrag" package I was able to substitute the tags in the figure with LaTeX text. Note that this also works with EPS figures directly created from MATLAB. This means I can add nifty equations, rotated labels and a few interesting fonts. Using LaTeX in tandem with "xdvi" (or "gv") you essentially get a pretty nice WYSIWYG typesetter. The final figure is:

 Of course, I can also scale the text or even the entire figure without any loss of resolution:
\begin{figure}
\begin{center}
\includegraphics[scale = 0.6]{Small_Chibi.eps}
\includegraphics[scale = 0.6, angle = 100]{Small_Chibi.eps}
\includegraphics[scale = 0.6, angle = 220]{Small_Chibi.eps}
\includegraphics[scale = 0.6, angle = 330]{Small_Chibi.eps}
\includegraphics[scale = 0.6, angle = 145]{Small_Chibi.eps}
\includegraphics[scale = 0.6, angle = -90]{Small_Chibi.eps}
\caption{Wheeeeeeeeeeeeeeeeeeee!!!}
\end{center}
\end{figure}


## Step 9: Pretty printing your MATLAB code!

 Another program which MATLAB users may find useful is A2ps, which converts plain ASCII text into PostScript, with the added bonus that it can "pretty print" code which is written in certain languages. I've written a couple of style sheets for it, but the one included in the distribution is for MATLAB 4.X. [Below] you will find a new style sheet for MATLAB 5.X. To use it, just copy it into your style sheets directory and modify the appropriate entry in "sheets.map" so that it reads: "*.m matlab5". Afterwards you can run it as shown below:
a2ps --prologue=color -Pfile coolplot.m


to get:

## Step 10: Getting the goodies

 Below is a list of all the programs mentioned above. Except for MATLAB, they're all free!

### Other sites of interest

There are other ways to get better mathematics in MATLAB plots than what the default environment provides. A good example of this is "stext" by [Douglas M. Schwarz]. It carries MATLAB's TeX functionality one step further, allowing one to perform some extra tricks. It's a bit of a tough call sometimes to decide what's the better approach (do all in MATLAB or let TeX take charge of all the text), but choice is always good :)




## Benchmarks

I've developed a MATLAB benchmark which complements "bench.m". It is a much more grueling and, hopefully, a better indicator of a machine's raw CPU power (it doesn't test graphics). Briefly, it runs a battery of 25 tests, including FFTs, mathematical operations on "small" and "large" matrices, various factorizations and eigenvalue calculations (both full and sparse). Note that the benchmark is designed for MATLAB 5.X.

Unfortunately it requires so much memory (256 Mb) that it can only run on one of the machines I have access to (SGI with dual R10Ks, takes 10 hours!) If you'd like to contribute to this benchmark please download [mbench.m] and e-mail me the results at [marco@atmosp.physics.utoronto.ca] (you will be credited). Aside from the resulting timings (which are stored in the cell array "times" if you do "times = mbench;", say), please send me also:

1. Which version of MATLAB you are using (i.e. type "ver" at the prompt)
2. The OS
3. The machine's model/vendor
4. Model, speed and number of CPUs
5. Amount of RAM
6. Cache size
7. Any other relevant info, e.g. was mbench running by itself?

• Version: MATLAB 5.3.0.10183 (R11)
• OS: IRIX64 6.5 01221553 IP25 mips
• Computer Model: SGI Challenge
• Processor(s): 2 194 MHZ MIPS 10000 IP25 Processors
• Main memory size: 256 Mbytes, 2-way interleaved
• Instruction cache size: 32 Kbytes
• Data cache size: 32 Kbytes
• Secondary unified instruction/data cache size: 1 Mbyte
• Author: Marco De la Cruz [marco@atmosp.physics.utoronto.ca]
• Full timings: [t_gyre.mat]
• Comments: The benchmark ran by itself overnight (no other major processes). Some tests used both CPUs. Unfortunately two tests were not timed correctly, see this table for details. This means that the MegabogoFLOPS is not really accurate :(

A full table is also available.

Thank you in advance for any contributions!

A new contribution by Tommy Binford (tbinford at gmail dot com). It's interesting to see how much faster his computer is (when I wrote the benchmark it was almost ludicrously slow, but I never thought those 10-second benchmarks made much sense to begin with). Here is his system: LEVIATHAN:
• Matlab Ver: 7.1.0.183 (R14) Service Pack 3, August 2, 2005
• OS: SuSE Linux 10.0
• Machine Model: Put together from parts
• CPU: AMD Opteron 275 (dual-dual core CPUs)
• RAM: 8GB
• Cache: 1MB per core (4 cores, but Matlab only uses one)

The numbers have been added to the table. Note from Tommy:

In my version of Matlab I had to add SIGMA to the final eigs test.  I used SIGMA=0.


Thanks for the submission!

 Well folks, I hope that some of you find this document useful. If you have any questions, comments, suggestions and/or complaints you can e-mail my agent at: [marco@atmosp.physics.utoronto.ca]. Visit too his way cool [Gunnm] web page! Have a good life, and always remember: you can tune a piano, but you cannot tuna fish! Bai!

| |

 Return to the [index]