0
votes

Situation: change Position of a single subplot with imagesc

%% Matlab recommends this structure if axes(); in loop
a1 = subplot(1,2,1); 
a2 = subplot(1,2,2); 
while 1    
    plot(a1, rand(3))    
    plot(a2, rand(3))    
    drawnow 
end

%% Test code
unitsPerInches=[0 0 15 15];
figure('Units', 'inches');
a1 = subplot(1,2,1); 
a2 = subplot(1,2,2); 
while 1    
    set(a1, 'Position', unitsPerInches); % TODO how to affect a1's Position here only? 
    imagesc(a1, rand(3))    
    imagesc(a2, rand(3))    
    drawnow 
end

Open

  1. What is imagesc corresponding structure to plot(a1,rand(3))?
  2. How to change Position of figure inside the loop?

Forward in Q1 - almost done

%% Extension to imagesc
figure
a1=subplot(1,2,1);
a2=subplot(1,2,2);
for counter=1:2;
    imagesc(a1,rand(3))
    imagesc(a2,rand(3))
    drawnow    
end

Fig. 1 Output of Docs example, Fig. 2 Output of Imagesc, Fig. 3 about Q2 where Position affects both subplots

enter image description here enter image description here enter image description here

Q1 is almost done; I have just forgotten how to get corresponding plot in imagesc; x-values should be put there but pseudocode imagesc(a1,XDATA,rand(3)) is unsuccessfuly.

Backward in Q2

Code

%% Extension to imagesc
unitsPerInches=[0 0 15 15];
figure
a1=subplot(1,2,1);
a2=subplot(1,2,2);
for counter=1:2;
    set(a1, 'Position', unitsPerInches); % TODO how to affect a1's Position here only?
    imagesc(a1,rand(3))
    imagesc(a1,rand(3))
    drawnow    
end

Output: position affects both images in Fig. 3.

I think I have misunderstood the meaning of Position here because so strange output.

Testing EBH's proposal for Q2

The implicit assignments cause problems when having two figures where subplots

unitsPerInches=[0 0 15 15];
aFig=figure();
a1=subplot(1,2,1);
a2=subplot(1,2,2);

bFig=figure();
b1=subplot(1,2,1);
b2=subplot(1,2,2);

for counter=1:2;
    if counter==1
        set(a1, 'Position', unitsPerInches); % affect only position of a1
    end
    subplot(1,2,counter);    
    imagesc(rand(3));
    drawnow    

    subplot(1,2,counter);    
    imagesc(rand(3));
    drawnow    
end

Output: second figure of subplots fails.

System: Linux Ubuntu 16.04 64 bit
Linux kernel 4.6
Matlab: 2016a
Related threads: Matlab7 'bug' when using "subplot" + "imagesc"?

2
Here a good answer to update from Matlab 2014 syntax to Matlab 2016 stackoverflow.com/a/39877470/54964 for subplots and having them in arrays. - Léo Léopold Hertz 준영

2 Answers

3
votes

I'm not 100% sure what you're asking, but I think it's about combining multiple imagesc statements while in a loop. I'd do something more direct -- use gca and put the subplot inside the loop. Quite often, if you want to programmatically address multiple images, it makes sense to put them in some sort of structure other than creating lots of differently named variables. Note also that while 1 is probably not really what you want -- it will hammer your graphics device drivers -- and that pause can take an argument to act as a wait function, for some fraction of a second if required.

testImages{1}=double(imread('coins.png')); 
testImages{2}=double(imread('cameraman.tif')); 

h=figure; 
set(h,'color','w'); %This handle refers to the background window 


for ix=1:2 
     subplot(1,2,ix); 
     imagesc(testImages{ix}); 
     axis equal;
     colormap gray; 

     %Change, for example, axis position
     curPoss=get(gca,'Position'); %gca stands for 'get current axis'
     set(gca,'Position',curPoss+1e-2*ix^2); %Move one image up a bit
end

Does that help?

enter image description here

1
votes

If you want to jump between figures, make an array of them, and use it within a loop:

unitsPerInches = [0.1 0.1 0.15 0.15];
figs = [figure(1) figure(2)];

for f = 1:numel(figs)
    figure(figs(f));
    for counter = 1:2;
        subplot(1,2,counter);
        imagesc(rand(3));
        drawnow
    end
    figs(f).Children(1).Position = unitsPerInches;
    figs(f).Children(2).Position = unitsPerInches+0.3;
end

Your original values for unitsPerInches was wrong, since the 'Position' property of an axes takes values between 0 to 1 by default. You can change this using the 'Units' property, like:

figs(f).Children(1).Units = 'inches';

The output from this example is two figures that looks like this:

fig_1

Where there is a small axes on the down-left and a big one on the top-right.

So, back to your original questions:

  1. What is imagesc corresponding structure to plot(a1,rand(3))?

Instead of passing the axes to imagesc, set the focus on the relevant figure, and subplot with:

figure(h)
subplot(x,y,c)
imagesc(data)

where h is a handle to the relevant figure, c is the place of the subplot within h where you want to plot the image (a number between 1 to x*y), and after these two line you call imagesc.

  1. How to change 'Position' of figure inside the loop?

In this question it is not clear if you want to change the 'Position' of the figure or the axes, they have different units and meaning, but both are accessible in the same way:

h.Position = [left bottom width height]; % for the position of the figure
h.Children(c).Position = [left bottom width height]; % for the position of the axes

where h is as before, but c may be numbered differently, so subplot(x,y,c) may not refer to the same axes as h.Children(c). However, you can always use gca to get the current axes handle:

ax = gca;
ax.Position = [left bottom width height];

Hope it's all clear now, and if there are further questions, let me know ;)