Tuesday, July 1, 2008

Programmatically saving Matlab figures

This problem has been bugging me a long time, and I've finally nailed it. So doing a whole bunch of Matlab processing, and instead of saving each figure by hand using the GUI, which can be tedious after more than a few figures, you'd like to have your code include these steps. (Using python and matplotlib of course, this is simple). Matlab does have the saveas to allow doing this, but it has two drawbacks for me:

  1. When I save figures, I usually maximize them so that the spacing looks better and I get higher resolution figures
  2. Regardless of the maximization, saveas resizes everything and you get (usually) a bad mix of spacing and font sizes. So many of my figures have labels and things that look like crap, with tick labels overlapping each other and other issues like this. At least, that's my experience using Matlab on Linux. At any rate, saveas does not normally give me figures I want to hand in with a homework assignment, let alone a presentation or a publication.

I have found a couple of nuggets that allow me to programmatically create graphics just like the ones I would have on screen. The first nugget, which solves the 2nd problem of resizing is as follows:

set(fig, 'PaperPositionMode', 'auto')

where fig is your figure handle. You can also just pass gcf. This wonderful little command, according to the Matlab documentation (where this was buried): "...ensures that the printed version is the same size as the onscreen version. With PaperPositionMode set to auto MATLAB does not resize the figure to fit the current value of the PaperPosition." Fantastic.

The second nugget is a way to set the figure size to fill the screen (I found this one in the Mathworks file share through a Google search):

set(fig,'units','normalized','outerposition',[0 0 1 1]);

You may or may not want to save and restore the original value of units around this call. At any rate, with these two commands, I can now create figures with my code that look how I want them without requiring any intervention on my part using the GUI. That's wonderful for making my workflow better.

8 comments:

Seb said...

Very useful, thank you! I like to add a third line (took me ages to figure out):

set(gca,'LooseInset',get(gca,'TightInset'))

this removes the excessive figure margins, and makes figures nice to import into documents without having to crop.

Unknown said...

Great, thanks
I suggest add tags
"maximize window before saving in matlab"

Unknown said...

This is the exactly what I was looking for!!! Very useful.

Thank you!!

homphysiology said...

Very useful! thanks

silly said...

The paperpositionmode property is what I needed - I automatically maximise using an undocumented hack, but figures were not looking nice once I would do print -deps; fonts would appear different and just generally bad. As noted, this is great for workflow - one does not wish to have to save all their figures by hand. This saved me hours of butthurt. Cheers

xsystem said...

I guess adjusting the dpi on the file name is the trick. Increase it to 600 dpi. Or tweak the image manually like this.
Something like this,

%Use the mentioned command as OP said,
set(gcf, 'PaperPositionMode', 'auto');
set(gcf,'units','normalized','outerposition',[0 0 1 1]);

%plot your data or figure
plot(time,data);

%set title meta data through command line
title('This is the title', 'FontSize', 16);
h = get(gca, 'title');
set(h, 'FontName', 'Arial');

%set x-axis lable manually with command line
xlabel('Time (seconds)', 'FontSize', 16);
h = get(gca, 'xlabel');
set(h, 'FontName', 'Arial');

%set y-axis lable manually with command line
ylabel('V_2 (volts)', 'FontSize', 16);
h = get(gca, 'ylabel');
set(h, 'FontName', 'Arial');

%Adjust ticks width through command line
set(gca,'FontSize',16, 'FontName', 'Arial');
set(gca,'LineWidth',2);

%Adjust legend position
legend('V_2','location','northeast');

%Print figure to png file - you can use tiff or something else
print -dpng -r600 Test1.png

Here -r600 is adjusting the dpi to 600. It could be less or more depending on what quality of image you want.
And there you go. You figure is pretty now.

Regards,
xsystem

Patrick Noffke said...

Awesome! Thank you and Seb for these tips!

Now I can create EPS files on Linux, use epstopdf, and the PDFs are perfect in a LaTeX document.

Thanks again!

Archit Gupta said...

you can also look into export_fig
it is submitted in matlab file exchange