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 :

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!

LadislavDear 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.

Patrick MartineauPost authorHi 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!

AurelieThis 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!

aris nikolaouThanks Buddy! Appreciate it!

Ashu ChoudharyDear 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

WalidHello, 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

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

Best,

Patrick

WalidThanks 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

XiangdongThank you patrick! Great job!

Sebastian ZaiserFor 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!

Raj kishoreExcellent job buddy

DiaaMany thanks for your informative post.

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

Thanks in advance

KristjanThank 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

Patrick MartineauPost authorHi 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

MichaelaThis 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

Pascale LelongPatrick, thanks very much for sharing this useful piece of code. I’ve often wrestled with subplots in Matlab and I’m usually on the losing end!

Pascale

schThanks 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!