Tobin Fricke's Lab Notebook
|Some Matlab tricks for making figures
||[Sep. 17th, 2007|07:50 pm]
When generating figures for publication from within Matlab, one annoyance (of many!) is the unnecessary whitespace that Matlab introduces. One would prefer Matlab to make the bounding box as tight as possible and let LaTeX handle the whitespace.
It turns out that an "axes" in Matlab has three properties which determine its positioning: OuterPosition, Position, and TightInset. OuterPosition gives the coordinates of the entire region within the current figure belonging to the axes. Position gives the region contained by the "data" region of the axes. TightInset gives the distance beyond this "data" region which is used by tick marks, labels, titles, and other decorations. Here's a sample plot with the OuterPosition illustrated in yellow, the Position in magenta, and the TightInset in red:
Notice the space between the red rectangle and the boundary of the image. Why is that there? We can eliminate it by setting Position to be equal to OuterPosition minus the margins given by TightInset:
set(gca, 'Position', get(gca, 'OuterPosition') - ...
get(gca, 'TightInset') * [-1 0 1 0; 0 -1 0 1; 0 0 1 0; 0 0 0 1]);
That little matrix is there because OuterPosition and Position are stored as
[x_0 y_0 width height] whereas TightInset is
[dx_left dy_bottom dx_right dy_top]. The results are:
Voilà! The offending whitespace has been removed. (For some reason, however, Matlab, seeing your modification of Position, takes it upon itself to compute a new, nonsensical value of OutsidePosition. This seems to be harmless...)
Another annoyance is in getting your figure to be the right size. Sure, you can scale your figure, but then the fonts will be the wrong size. The easiest thing to do is to estimate the desired size of your final figure, and have Matlab generate the figure in the correct size to begin with. The trick is to force not just the PaperSize but also the PaperPosition. If we want a figure 6.25 inches by 7.5 inches, we would do this:
set(gcf, 'PaperUnits', 'inches');
set(gcf, 'PaperSize', [6.25 7.5]);
set(gcf, 'PaperPositionMode', 'manual');
set(gcf, 'PaperPosition', [0 0 6.25 7.5]);
A yet further annoying situation is this: you dutifully utilize PDF or EPS files for your figures, and yet they appear to be included as ugly, non-scalable raster graphics! I encountered this problem just today. Matlab allows you to choose between several renderers, which determine just how your figures get made. Suppose you have utilized transparency in your figure, yet are asking Matlab to output a figure to PDF, which (in the version supported by Matlab) does not support transparency. What's Matlab to do? Here's what it does do: it takes a screenshot, producing a bitmap, which is then wrapped in EPS or PDF. Doh!
The trick is to ask Matlab to use the "painters" renderer. It does not support transparency, but at least you're guaranteed vector graphics output:
set(gcf, 'renderer', 'painters');
Finally, just for the sake of completeness, you might want to actually generate your output file:
print(gcf, '-dpdf', 'my-figure.pdf');
print(gcf, '-dpng', 'my-figure.png');
print(gcf, '-depsc2', 'my-figure.eps');
It would be nice if LaTeX could tell Matlab the available space for a figure, and have an appropriately sized/proportioned figure generated on the fly... but one can see that going down that road would give us OLE
It seems this scheme is not foolproof. Matlab seems to misestimate the space required by labels/titles/etc.
Additionally, the "TightInset" size, expressed in "Normalized Coordinates" will change as you scale the image, since the fraction of the image taken up by labels will decrease as you increase the size of the image. Not sure of a good way around this.
/me prefers gnuplot + xmgrace for datasets, and final trickery in GIMP.
If you're doing final trickery in GIMP... that means you're using bitmapped images, and lack vector graphics goodness!
yeah, you got me :) But it's so easy!
I'm still looking for alternatives, but xmgrace really does work well. It even does DFT/FFT, histograms, running averages, etc. on loaded data sets. Really handy. GNUplot just makes things really pretty.
Have you used anything outside of matlab for graphics/plotting? any recommendations?
Python with gnuplot extensions are also pretty killer. I've heard good things about the matplotlib. Have you been python coding much?
I don't use Python at all. I think it's a reasonably decent language, though, despite having some annoyances.
2008-05-21 04:58 pm (UTC)
Hi, very useful tips, thanks.
I've also found that I want to insert Matlab figures into presentations, in particular Keynote. I don't want to the background painted white/gray or whatever color.
If you set the axis and figure background colors to 'none', then they become transparent:
set(gcf, 'Color', 'none');
(obviously you can be selective about this.)
PDF export does honor the 'none' color, and the axes will not be filled. ("print -dpdf")
EPS export does not appear to honor the 'none' color.
What about subplotting? How would this be applied to a figure composed of subplots?