MATLAB figures

From Fluids Wiki
Jump to navigation Jump to search

This page describes the best practices for making figures in MATLAB for inclusion in a LATEX document

Setting figure size

Most of the time you will want to choose vector graphics, that is, use MATLAB's "painters" renderer. Code to select this is:

set(gcf,'renderer','painters');

Now you need to decide what the size of the figure should be. For a standard LaTeX report, we might want the plot to span the width of the page (ex: 6 inches wide) and half as tall (3 inches). To set 6x3 inch we use

set(gcf, 'PaperUnits', 'inches', 'PaperSize', [6 3],'PaperPosition',[0 0 6 3]);

Here is where you plot something.

plot(0:0.1:3, exp(-[0:0.1:3]));

Now you print to a PDF file.

print('-dpdf','filename.pdf');

Here are the above commands in one easy to copy-paste block,

set(gcf,'renderer','painters');
set(gcf, 'PaperUnits', 'inches', 'PaperSize', [6 3],'PaperPosition',[0 0 6 3]);
plot(0:0.1:3, exp(-[0:0.1:3]));
print('-dpdf','filename.pdf');

Inclusion in LaTeX

Use the following code to include the PDF figure in your LaTeX document.

\begin{figure}
  \centering
  \includegraphics{filename.pdf}
  \caption{Description goes here.}
  \label{label:here}
\end{figure}

Pcolor vs. contourf

Pcolor is often not the best way to produce a heatmap if you plan to use vector graphics. The reason is that each data point becomes two triangular elements in the PDF file, and when you have a large number of elements it produces a large file which can be very slow to display/print. For most purposes, contourf is a superior replacement for pcolor. The code below demonstrates pcolor in figure 1 and contourf in figure 2.

x=linspace(0,100,1000); [X,Y]=meshgrid(x,x); data=X.*Y;
figure(1); pcolor(X,Y,data); shading flat
figure(2); [ch,ch]=contourf(X,Y,data,100); set(ch,'edgecolor','none');

Subplot magic

MATLAB's subplot command is useful but it's not always the best at making multi-panel figures. Following is an example script that creates four subplots, sets their size and location, and adds a single colourbar along the bottom. The example produces a figure that is 6 inches wide and 6.5 inches tall. It will fit into a standard LaTeX document without any scaling. The text size on the figure will be the same in your LaTeX.

The default output from MATLAB looks like this: Subplot Default. The problems are (a) colourbar is "squishing" the lower right panel, (b) the spacing between figures is too large wasting precious page space, and (c) too much white space around the edges.

The result of this script is here: Subplot Adjusted. All of the problems are fixed. The main rule of thumb to follow is that all of the subplot repositioning and resizing should be performed after all the plots have been drawn. If this is not done in the correct sequence, the plot may not be displayed properly.

clear; clf;

% create four subplots, store handles in A, B, C and D and colorbar in E
A=subplot(2,2,1); imagesc(magic(6)); caxis([0 75]); xlabel('x (m)'); ylabel('y (m)');
B=subplot(2,2,2); imagesc(magic(7)); caxis([0 75]); xlabel('x (m)'); ylabel('y (m)');
C=subplot(2,2,3); imagesc(magic(8)); caxis([0 75]); xlabel('x (m)'); ylabel('y (m)');
D=subplot(2,2,4); imagesc(magic(9)); caxis([0 75]); xlabel('x (m)'); ylabel('y (m)');
E=colorbar('Location','Southoutside');

% Specify some parameters for the plot
x0   = 0.5;  % spacing between and around figures (inches)
y0   = 1;    % offset from the bottom (inches)
w    = 2.25; % size of each subfigure (w x w inches)
y0cb = 0.25; % offset of colourbar from botom (inches)

% Now specify each figure's location and dimensions
% as [x  y  width  height]:
% 'x' and 'y' are position of the lower-left corner of each panel
% 'length' and 'height' are the dimensions of each panel
set(A,'Units','inches','Position',[x0     y0+w+x0  w w]);
set(B,'Units','inches','Position',[w+2*x0 y0+w+x0  w w]);
set(C,'Units','inches','Position',[x0     y0       w w]);
set(D,'Units','inches','Position',[w+2*x0 y0       w w]);

set(E,'Units','inches','Position',[x0+0.25*w   y0cb   1.5*w+x0   0.25]);

% total width, height
W=3*x0 + 2*w;      % three spacing and two panels wide
H=2*w + 2*x0 + y0; % two spacing, two panels and one y0 in height
fprintf('Figure is %.2fin wide, %.2fin tall\n',W,H);
set(gcf, 'PaperUnits', 'inches', 'PaperSize', [W H],'PaperPosition',[0 0 W H]);
set(gcf, 'Renderer', 'Painters');

print -dpdf output.pdf

Converting PDF figures to grayscale using the command-line

Many journals charge fees to print figures in colour, so it is often desirable to be able to convert existing colour figures to grayscale rather than rendering them all over again. As this blog post (http://handyfloss.net/2008.09/making-a-pdf-grayscale-with-ghostscript/) points out, this can be achieved with ghostscript (gs) as follows:

gs -sOutputFile=grayscale.pdf -sDEVICE=pdfwrite \
-sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray \
-dCompatibilityLevel=1.4 -dNOPAUSE -dBATCH color.pdf

where 'color.pdf' is the input pdf and 'grayscale.pdf' is the output pdf. Since it may be difficult to remember all the options, the author also saved us some trouble by writing a perl-script that remembers the options for us:

Create a file called 'pdf2gray.pl' in your ~/bin/ folder and make it executable with chmod 755 pdf2gray.pl, put the following text in that file:

#!/usr/bin/perl -w
use strict;
my $infile = $ARGV[0];
my $outfile = $infile;
$outfile =~ s/\.pdf$//;
$outfile = $outfile._gray.pdf;
system gs -sOutputFile=$outfile -sDEVICE=pdfwrite -sColorConversionStrategy=Gray -dProcessColorModel=/DeviceGray -dCompatibilityLevel=1.4 -dNOPAUSE -dBATCH $infile

You should now be able to convert colour pdf-files to grayscale by calling pdf2gray.pl myfile.pdf. It will produce the grayscale output in 'myfile_gray.pdf'.