Removing deadspace in subplots while retaining title & labels

不问归期 提交于 2019-11-30 15:40:00

问题


Hi I have a problem in matlab I want to create a figure containing 10 subplots. in 2X5 orientation. But the problem is that I want to reduce the deadspace area between them. I also require to keep the title, xlabel for the first row of images & the xlabel(only) for the second row of images. No ylabels are required.

Till now I have done this code (for the first row): Once I figure the first row , the second row should be a piece of cake.

close all

figure,set(gca,'Color','none')
subplot(2,5,1);subplot('Position',[0.02 0.51  0.18 0.45]);get(gca,'position');set(gca, 'XTick', []);set(gca, 'YTick', []);
imshow(I);hold on; axis off;
contour((BW(:,:,1)), [0 0], 'r','LineWidth',2);
hold off;title('1st curve','FontSize',12);xlabel('(a)','FontSize',12)
subplot(2,5,2);subplot('Position',[0.215 0.51  0.18 0.45]);get(gca,'position');set(gca, 'XTick', []);set(gca, 'YTick', []);
imshow(I);hold on; axis off;
contour((BW(:,:,2)), [0 0], 'r','LineWidth',2);
hold off;title('2nd curve','FontSize',12);xlabel('(b)','FontSize',12)
subplot(2,5,3);subplot('Position',[0.410 0.51  0.18 0.45]);get(gca,'position');set(gca, 'XTick', []);set(gca, 'YTick', []);
imshow(I);hold on; axis off;
contour((BW(:,:,3)), [0 0], 'r','LineWidth',2);
hold off;title('3rd curve','FontSize',12);xlabel('(c)','FontSize',12)
subplot(2,5,4);subplot('Position',[0.605 0.51  0.18 0.45]);get(gca,'position');set(gca, 'XTick', []);set(gca, 'YTick', []);
imshow(I);hold on; axis off;
contour((BW(:,:,4)), [0 0], 'r','LineWidth',2);
hold off;title('4th curve','FontSize',12);xlabel('(d)','FontSize',12)
subplot(2,5,5);subplot('Position',[0.8 0.51  0.18 0.45]);get(gca,'position');set(gca, 'XTick', []);set(gca, 'YTick', []);
imshow(I);hold on; axis off;
contour((BW(:,:,5)), [0 0], 'r','LineWidth',2);
hold off;title('5th curve','FontSize',12);xlabel('(e)','FontSize',12)

This gives me an output like this :

As you can see the fourth image is not present. What is wrong with the code ? I have rechecked my code several times and the computations too but could not find any error.

Interestingly when I run this code [only having the 4th subplot]

subplot(2,5,4);subplot('Position',[0.605 0.51  0.18 0.45]);get(gca,'position');set(gca, 'XTick', []);set(gca, 'YTick', []);
imshow(I);hold on; axis off;
contour((BW(:,:,4)), [0 0], 'r','LineWidth',2);
hold off;title('4th curve','FontSize',12);xlabel('(d)','FontSize',12)

I get this answer !!

Please can anyone tell me where am I wrong ? Note I do require the xlabel and the title for the first row of the images.

EDIT: I then went and did this thing. Now I get the five images. However the spacing between the images in all the cases are not uniform, specifically spacing between 1st & 2nd image is different from the rest.

My code :

close all

figure,set(gca,'Color','none')
subplot(2,5,1);subplot('Position',[0.02 0.51  0.18 0.45]);get(gca,'position');set(gca, 'XTick', []);set(gca, 'YTick', []);
imshow(I);hold on; axis off;
contour((BW(:,:,1)), [0 0], 'r','LineWidth',2);
hold off;title('1st curve','FontSize',12);xlabel('(a)','FontSize',12)
subplot(2,5,2);subplot('Position',[0.210 0.51  0.18 0.45]);get(gca,'position');set(gca, 'XTick', []);set(gca, 'YTick', []);
imshow(I);hold on; axis off;
contour((BW(:,:,2)), [0 0], 'r','LineWidth',2);
hold off;title('2nd curve','FontSize',12);xlabel('(b)','FontSize',12)
subplot(2,5,3);subplot('Position',[0.405 0.51  0.18 0.45]);get(gca,'position');set(gca, 'XTick', []);set(gca, 'YTick', []);
imshow(I);hold on; axis off;
contour((BW(:,:,3)), [0 0], 'r','LineWidth',2);
hold off;title('3rd curve','FontSize',12);xlabel('(c)','FontSize',12)
subplot(2,5,4);subplot('Position',[0.600 0.51  0.18 0.45]);get(gca,'position');set(gca, 'XTick', []);set(gca, 'YTick', []);
imshow(I);hold on; axis off;
contour((BW(:,:,4)), [0 0], 'r','LineWidth',2);
hold off;title('4th curve','FontSize',12);xlabel('(d)','FontSize',12)
subplot(2,5,5);subplot('Position',[0.795 0.51  0.18 0.45]);get(gca,'position');set(gca, 'XTick', []);set(gca, 'YTick', []);
imshow(I);hold on; axis off;
contour((BW(:,:,5)), [0 0], 'r','LineWidth',2);
hold off;title('5th curve','FontSize',12);xlabel('(e)','FontSize',12)

Now I get this answer :

How can I correct this? Pleae help! Thanks in advance!!

EDIT : I seems to have solved this problem. Please seem my answer below. However I do have query. I wanted to make the code run in loops and so implemented this code .

I = imread('coins.png');
I = imresize(I,[128 128]);
for no = 1:5
    subplot('Position',[0.025+0.19*(no-1) 0.51 0.19 0.48]);
    imshow(I);
    get(gca,'Position');set(gca, 'XTick', []);set(gca, 'YTick', []);
    title({'Image' num2str(no)});
    subplot('Position',[0.025+0.19*(no-1) 0.03  0.19 0.48]);
     imshow(I);
    get(gca,'Position');set(gca, 'XTick', []);set(gca, 'YTick', []);
    title({'Image' num2str(no)});
end

The answer comes out as this

Can this code be vectorised ??


回答1:


The built in subplot function is really powerful and nice. Instead of going with custom computed positions, I think it is best to stick with subplot. The problem of course is that subplot sticks in "extra" space. This space is controlled by two factors. The first is the user controlled SubplotDefaultAxesLocation property of the application data of figures. The second is a hardcoded inset within the subplot function. The SubplotDefaultAxesLocation property controls the whitespace around the edge of the figure while the inset controls the space between the panels. You can remove the space around the figure with

hfig = figure;
setappdata(hfig, 'SubplotDefaultAxesLocation', [0, 0, 1, 1])

To remove the space between panels you need to edit (or copy edit) subplot.m In R2013a the offending lines are 129 and 130

% This is the percent offset from the subplot grid of the plotbox.
inset = [.2, .18, .04, .1]; % [left bottom right top]

If you change line 130 to be

inset = [0.0, 0.0, 0.0, 0.0]; % [left bottom right top]

then the panels will not have any space between them. Even better would be something like

% This is the percent offset from the subplot grid of the plotbox.
if ~isappdata(ancestorFigure, 'SubplotDefaultInset')
    inset = [.2, .18, .04, .1]; % [left bottom right top]
else
    inset = getappdata(ancestorFigure, 'SubplotDefaultInset');
end

so you can control the inset. With this slightly modified subplot function

I = imread('coins.png');
I = imresize(I,[128 128]);

voffset = 0.3;
hfig = figure;
setappdata(hfig, 'SubplotDefaultAxesLocation', [0, voffset/2, 1, 1-voffset]);
setappdata(hfig, 'SubplotDefaultInset', [0, 0, 0, 0]);

nrow = 2;
ncol = 5;
hax = nan(nrow, ncol);
for irow = 1:nrow
    for icol = 1:ncol
        hax(irow, icol) = mysubplot(nrow, ncol, icol+(irow-1)*ncol, 'align');
        imshow(I);
        if irow == 1
            title(hax(irow, icol), ['Curve #', num2str(icol)], 'FontSize',12);
        end
        if irow == nrow
            xlabel(hax(irow, icol), ['(', char(96+icol), ')'], 'FontSize',12);
        end
    end
end
set(hax,  'XTick', [], 'YTick', []);

pos = get(hfig, 'Position');
set(hfig, 'Position', [pos(1:2), (1-voffset)*pos(3), nrow/ncol*pos(3)]);

You need the voffset to allow the title and xlabel to fit on the figure. You need to scale the figure so that it has the correct aspect ratio to handle the panels. The result is

The small gap between curve 1 and 2 and curve 3 and 4 appears to be a rendering artefact.

If you want the labels between the rows, you need to add some extra space. For example to add just labels on the x axis you can do

voffset = 0.35;
setappdata(hfig, 'SubplotDefaultAxesLocation', [0, voffset/4, 1, 1-voffset/2]);
setappdata(hfig, 'SubplotDefaultInset', [0, voffset/2, 0, 0]);



回答2:


The subaxis funcion you can find here at the Matlab File Exchange: subaxis by Aslak Grinsted offers you a very convenient solution.




回答3:


when subplots overlap, the earlier one is hidden.

try slightly decreasing the 'Position' width.

they should show up again

also, there could be some "snap to grid" issues, how does this behave when you resize the window?




回答4:


close all
figure,set(gca,'Color','none')
subplot('Position',[0.025 0.51  0.19 0.48]);get(gca,'position');set(gca, 'XTick', []);set(gca, 'YTick', []);
imshow(I);hold on; axis off;
contour((BW(:,:,1)), [0 0], 'r','LineWidth',2);
hold off;title('1st curve','FontSize',12);h=xlabel('(a)','FontSize',12);
s=get(h,'Position');
s(2)=s(2)-28;
set(h,'Position',s);
subplot('Position',[0.025+0.19*1 0.51  0.19 0.48]);get(gca,'position');set(gca, 'XTick', []);set(gca, 'YTick', []);
imshow(I);hold on; axis off;
contour((BW(:,:,2)), [0 0], 'r','LineWidth',2);
hold off;title('2nd curve','FontSize',12);h=xlabel('(b)','FontSize',12);
s=get(h,'Position');
s(2)=s(2)-28;
set(h,'Position',s);
subplot('Position',[0.025+0.19*2 0.51  0.19 0.48]);get(gca,'position');set(gca, 'XTick', []);set(gca, 'YTick', []);
imshow(I);hold on; axis off;
contour((BW(:,:,3)), [0 0], 'r','LineWidth',2);
hold off;title('3rd curve','FontSize',12);h=xlabel('(c)','FontSize',12);
s=get(h,'Position');
s(2)=s(2)-28;
set(h,'Position',s);
subplot('Position',[0.025+0.19*3 0.51  0.19 0.48]);get(gca,'position');set(gca, 'XTick', []);set(gca, 'YTick', []);
imshow(I);hold on; axis off;
contour((BW(:,:,4)), [0 0], 'r','LineWidth',2);
hold off;title('4th curve','FontSize',12);h=xlabel('(d)','FontSize',12);
s=get(h,'Position');
s(2)=s(2)-28;
set(h,'Position',s);
subplot('Position',[0.025+0.19*4 0.51  0.19 0.48]);get(gca,'position');set(gca, 'XTick', []);set(gca, 'YTick', []);
imshow(I);hold on; axis off;
contour((BW(:,:,5)), [0 0], 'r','LineWidth',2);
hold off;title('5th curve','FontSize',12);h=xlabel('(e)','FontSize',12);
s=get(h,'Position');
s(2)=s(2)-28;
set(h,'Position',s);

subplot('Position',[0.025 0.03  0.19 0.48]);get(gca,'position');set(gca, 'XTick', []);set(gca, 'YTick', []);
seg = phi0(:,:,1)<=0;imshow(seg);
h=xlabel('(f)','FontSize',12);
s=get(h,'Position');
s(2)=s(2)-28;
set(h,'Position',s);
subplot('Position',[0.025+0.19*1 0.03  0.19 0.48]);get(gca,'position');set(gca, 'XTick', []);set(gca, 'YTick', []);
seg = phi0(:,:,2)<=0;imshow(seg);
h=xlabel('(g)','FontSize',12);
s=get(h,'Position');
s(2)=s(2)-28;
set(h,'Position',s);
subplot('Position',[0.025+0.19*2 0.03  0.19 0.48]);get(gca,'position');set(gca, 'XTick', []);set(gca, 'YTick', []);
seg = phi0(:,:,3)<=0;imshow(seg);
h=xlabel('(h)','FontSize',12);
s=get(h,'Position');
s(2)=s(2)-28;
set(h,'Position',s);
subplot('Position',[0.025+0.19*3 0.03  0.19 0.48]);get(gca,'position');set(gca, 'XTick', []);set(gca, 'YTick', []);
seg = phi0(:,:,4)<=0;imshow(seg);
h=xlabel('(i)','FontSize',12);
s=get(h,'Position');
s(2)=s(2)-28;
set(h,'Position',s);
subplot('Position',[0.025+0.19*4 0.03  0.19 0.48]);get(gca,'position');set(gca, 'XTick', []);set(gca, 'YTick', []);
seg = phi0(:,:,5)<=0;imshow(seg);
h=xlabel('(j)','FontSize',12);
s=get(h,'Position');
s(2)=s(2)-28;
set(h,'Position',s);

Thanks everybody I got the correct answer. I changed my code a bit.

This was the answer I got :




回答5:


Of course it can be done with a single loop (using a cell array for your variables, and one for the plotting functions ) but for simplicity i would just lump it as two loops .

labels = {'(a)' , '(n)' , '(etc)' , 'asdf','asddf'}
jay=1
for aye =1:5
     subplot('Position',[0.025+0.19*(aye-1) 0.51-0.48*(jay-1)  0.19 0.48]);
    ...
     h=xlabel(labelsabc{aye},'FontSize',12);
     ....
end


来源:https://stackoverflow.com/questions/18853962/removing-deadspace-in-subplots-while-retaining-title-labels

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!