# How to remove subplot grey space between images

95 views (last 30 days)
Francisco Rogel on 8 Dec 2016
Commented: jiro on 8 Dec 2016
I am trying to remove the space between and cannot figure it out. I have tried many ways and nothing is working. Is there a way to remove the space between or maybe a different way to approach this problem. The goal is to have the images touching in a grid like way
This is what prints:
grayScaleImage = rgb2gray(theImage);
theGrayImage = grayScaleImage > 100;
[height, width, dim] = size(theImage);
numRecsAcross = 4;
numRecsDown = 4;
xmin = 1;
ymin = 1;
width = (width/numRecsAcross);
height = (height/numRecsDown);
xmin = uint16(xmin);
ymin = uint16(ymin);
width = uint16(width);
height = uint16(height);
s = 1;
for i = 1: numRecsDown
for j = 1: numRecsAcross
block = theImage(ymin+i-i:height*i, xmin+j-j:width*j, :);
color = uint8(mean(mean(block)));
rr = color(:,:,1);
gg = color(:,:,2);
bb = color(:,:,3);
RedChannel = 255 * uint8(theGrayImage);
BlueChannel = 255 * uint8(theGrayImage);
GreenChannel = 255 * uint8(theGrayImage);
r = ((double(rr))/255) * RedChannel;
g = ((double(gg))/255) * GreenChannel;
b = ((double(bb))/255) * BlueChannel;
rgbImage = cat(3, r, g, b);
subplot(numRecsAcross,numRecsAcross,s);
imshow(rgbImage);
s = s+1;
end
end

jiro on 8 Dec 2016
Edited: jiro on 8 Dec 2016
One way is to use subplot or axes to manually specify a tight region. In your code, change the subplot line to
subplot('Position',[(j-1)*1/numRecsAcross (numRecsDown-i)*1/numRecsDown 1/numRecsAcross 1/numRecsDown])
This simply calculates and sets the coordinates ([left bottom width height]) of each set of axes.
Another way is if you have Image Processing Toolbox, you can use the montage function. Remove your call to subplot and imshow. Instead, build a MxNx3xK array of images inside your loop.
allImage(:,:,:,s) = rgbImage;
Then outside of the loop, plot using montage.
montage(allImage,'Size',[numRecsDown numRecsAcross])
jiro on 8 Dec 2016
If maintaining the aspect ratio is important, you're better off using montage or doing what Chaya is recommending.

Iddo Weiner on 8 Dec 2016
Try the following trick - instead of specifying the "real" exact number of subplots you need, specify a greater number and then for the 3rd input of subplot() specify a range instead of a number.
Example - say I want to plot 4 panels, and want smaller margins between panels. So instead of going:
subplot(2,2,1)
...
subplot(2,2,4)
I'll define: subplot(M,N,Xi) - where M,N are the dimensions of the plot (and I will suggest setting them to an integer larger than 2), and Xi is a vector defining the location of subplot i. Here's an example in which M=N=4 (data is random):
figure
subplot(4,4,[1,2,5,6])
bar(normrnd(0,1,100,1))
subplot(4,4,[3,4,7,8])
histogram(normrnd(0,1,100,1))
subplot(4,4,[9,10,13,14])
bar(normrnd(0,1,100,1))
subplot(4,4,[11,12,15,16])
histogram(normrnd(0,1,100,1))
Now, you can play around with M and N (don't forget to adjust the range accordingly). This won't actually change the absolute dimensions of the whole figure but it will get rid of the margin space between panels. Of course - the bigger M,N are - the less margin you'll have..
Hope this helps
jiro on 8 Dec 2016
There's also a similar example in the documentation:

Chaya N on 8 Dec 2016
Edited: Chaya N on 8 Dec 2016
The best (and possibly only) way to do that would be to create a new, larger image where you combine all your smaller subplots in the order that you need. For example, say you had four images A,B,C and D all of size m-by-n and you wanted them in a grid, then you would create a new image X of size 2m-by-2n and pass values as:
X(1:m, 1:n) = A;
X(1:m, n+1 : 2*n) = B;
X(m+1 : 2*m, 1:n) = C;
X(m+1 : 2*m, n+1 : 2*n) = D;
and then plot X.
jiro on 8 Dec 2016
In your code you can do the following. I'm just including code at the end.
rgbImage = cat(3, r, g, b);
acrossImages{j} = rgbImage;
s = s+1;
end
downImages{i} = cat(2,acrossImages{:});
end
bigImage = cat(1,downImages{:});
imshow(bigImage)