Perfect subplot in Matlab

In my field, it is often very useful to include many panels in one single figure. Matlab offers by default the subplot function but it is not easily customizable and often leaves me unsatisfied. For high quality publishable figures, I wrote the function subplot_pos :

function [ positions ] = subplot_pos(plotwidth,plotheight,leftmargin,rightmargin,bottommargin,topmargin,nbx,nby,spacex,spacey)
 
    subxsize=(plotwidth-leftmargin-rightmargin-spacex*(nbx-1.0))/nbx;
    subysize=(plotheight-topmargin-bottommargin-spacey*(nby-1.0))/nby;
 
    for i=1:nbx
       for j=1:nby
 
           xfirst=leftmargin+(i-1.0)*(subxsize+spacex);
           yfirst=bottommargin+(j-1.0)*(subysize+spacey);
 
           positions{i,j}=[xfirst/plotwidth yfirst/plotheight subxsize/plotwidth subysize/plotheight];
 
       end
    end
end

This function takes the size of the panels and the figure in centimeters as parameters and outputs a cell containing axes positions. The resulting figure has the exact specified dimensions. The following code shows how to use this Matlab sub-plotting function :

%parameters for figure and panel size
plotheight=20;
plotwidth=16;
subplotsx=3;
subplotsy=5;   
leftedge=1.2;
rightedge=0.4;   
topedge=1;
bottomedge=1.5;
spacex=0.2;
spacey=0.2;
fontsize=5;    
sub_pos=subplot_pos(plotwidth,plotheight,leftedge,rightedge,bottomedge,topedge,subplotsx,subplotsy,spacex,spacey);
 
%setting the Matlab figure
f=figure('visible','on')
clf(f);
set(gcf, 'PaperUnits', 'centimeters');
set(gcf, 'PaperSize', [plotwidth plotheight]);
set(gcf, 'PaperPositionMode', 'manual');
set(gcf, 'PaperPosition', [0 0 plotwidth plotheight]);
 
%loop to create axes
for i=1:subplotsx
for ii=1:subplotsy
 
ax=axes('position',sub_pos{i,ii},'XGrid','off','XMinorGrid','off','FontSize',fontsize,'Box','on','Layer','top');
 
z=peaks;
contour(z);
 
if ii==subplotsy
title(['Title (',num2str(i),')'])
end
 
if ii>1
set(ax,'xticklabel',[])
end
 
if i>1
set(ax,'yticklabel',[])
end
 
if i==1
ylabel(['Ylabel (',num2str(ii),')'])
end
 
if ii==1
xlabel(['Ylabel (',num2str(i),')'])
end
 
end
end
 
%Saving eps with matlab and then producing pdf and png with system commands
filename=['test'];
print(gcf, '-depsc2','-loose',[filename,'.eps']);
system(['epstopdf ',filename,'.eps'])
system(['convert -density 300 ',filename,'.eps ',filename,'.png'])

And the resulting figure looks like :

Perfect subplot with Matlab

Custom subplot function for Matlab. Publishable quality figures.

If you display the figure at 100% of its size and measure it with a ruler, you will see that the figure respects perfectly the dimensions specified in the code. This code is fully customizable and can be modified to suit your needs. Anything is possible… Much better than the default Matlab subplot function!

17 thoughts on “Perfect subplot in Matlab

  1. Ladislav

    Dear Patrick,

    good job, thanks for publishing it!
    I was fighting with the Matlab ‘subplot’ function to display a composition of 10×7 plots for hours, with no success… and finally I bumped into your perfect, customizable code that works, and what is more, it produces really nice results. Thumbs up!

    L.

    Reply
    1. Patrick Martineau Post author

      Hi Ladislav, I am glad it was useful to you! Matlab’s built-in function is fine for a few panels but I can imagine it must have been a nightmare for a combination of 70 panels!

      Reply
  2. Aurelie

    This is great. I think I will try to add a linkaxes option, and condense it all into a single function to get axes position and figure.
    Thanks!

    Reply
  3. Ashu Choudhary

    Dear Patrick,

    your function provided a really great help for my 6*4 (row*column) subplots. I was struggling a lot initially 🙂

    Thank you so much for sharing !

    Best Regards,

    Ashu

    Reply
  4. Walid

    Hello, great job thanks for this work, please i am a beginner in Matlab Software, i would like to have just 3 rows and 2 columns but how to set them to take the whole page A4 size.
    Thank you

    Reply
    1. Patrick Martineau Post author

      Hi Walid, I would set “plotwidth” and “plotheight” to the size of the A4 page which is 21 by 29.7.
      Best,
      Patrick

      Reply
      1. Walid

        Thanks for your reply, the fact i am a little stuck, if you can help please how to set each plot its own fucntion, i mean, here it is a loop z=peaks, i would like to plot different curves , should i use subplot(3,2,1) and so on or no?
        Best,
        Walid

        Reply
  5. Sebastian Zaiser

    For years and years you fight with the subplot-features of Matlab or Pythons Matplotlib. You get the results you want, but it again and again seems like a struggle. Then you stumble upon this, and it just works.

    Thank you!

    Reply
  6. Diaa

    Many thanks for your informative post.

    Additionally, how can I put a single colorbar spanning the whole figure either vertically or horizontally?

    Thanks in advance

    Reply
  7. Kristjan

    Thank you for your excellent work.
    However, I receive the error message at system([‘epstopdf ‘,filename,’.eps’]):

    ‘epstopdf’ is not recognized as an internal or external command,
    operable program or batch file.

    ans =

    1

    Invalid Parameter – 300

    ans =

    4

    I could find script eps2pdf, but this will not get it working either. I could get the pdf through GSviewer, but I’m still wondering what might be the issue.

    Regards
    Kristjan

    Reply
    1. Patrick Martineau Post author

      Hi Kristjan,
      By using system(”), you may do anything you can normally do in the terminal, so it will depend on which software is available on your machine. I suggest you look at the documentation. eps2pdf may need different options than epstopdf. If you can get it to work in your terminal, then you can modify the call accordingly in Matlab.
      Best,
      Patrick

      Reply
  8. Michaela

    This is exactly what I was looking for and the code is easy to customize – you made my day!

    Thanks a lot Patrick and all the best,
    Michaela

    Reply
  9. sch

    Thanks for sharing your script for this hard work!
    I have a problem for using your script to make subplot figures.

    ==== Error message ====
    This statement is not inside any function.
    (It follows the END that terminates the definition of the function “subplot_pos”.)

    Do you know where comes trouble?

    Thank you for your help!

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *