geojanm
geojanm

Reputation: 33

Positioning of annotations in subplots

I have to generate a plot of different sensor data. These should be printed in subplot each. After generating the plot it should be annotated with some rectangles to highlight different features. Afterwards, these rectangles should be annotated with a text, describing the belonging class with a short word.

Surprisingly the same code is working in another script, where I don't use subplots, but only a single specgram. I already replace the annotation(h,...) with annotation(gcf, ...), which should be the same. Adding tempplot instead of h, which makes sense to me,

Sensorinput = rand(100,6);
Naminginput = {'a' 'b' 'c' 'd' 'e' 'f'}
sampledExperiment = [10, 10, 0;
                 30,10, 1; 
                 50,10, 0; 
                 70,10, 1; 
                 ]

experimentnaming = {0, 'classA';
                1, 'classB'
                }

samplerate = 10;                    

h = figure;
for index = 1:1:length(Sensorinput(1,:))
  tempplot = subplot(length(Sensorinput(1,:)),1,index);  
  plot(Sensorinput(:,index));
  title(Naminginput(index));
  pos = get (tempplot, 'position')
  step = pos(3)/length(Sensorinput(:,index));


  for index=1:1:length(sampledExperiment)

    annotation(h, "rectangle",[pos(1)+step*sampledExperiment(index,1),pos(2),step*sampledExperiment(index,2),pos(4)]);
    y  = ylim;
    for namingindex=1:1:length(experimentnaming(:,1))  
      if experimentnaming{namingindex,1}==sampledExperiment(index,3)
          text(sampledExperiment(index,1)/samplerate,y(2),experimentnaming(namingindex,2),'rotation',90);
      end
    end

  end

end

I expect the boxes having the same height than the underlying subplot. Also, I am expecting the text (which is obviously printed as a stack) as an annotation to the box. But this is the result I currently get: wrong result. Also, the boxes do not zoom correctly, when I resize the window. wrong_small_window. This is mainly, what is working: working with single figure. Draw rectangles with the full height of the subplot and add text. This is created with the same code, but without subplots.

Hopefully you can help?

Upvotes: 1

Views: 1009

Answers (2)

geojanm
geojanm

Reputation: 33

I just managed to get what I want by using a direct rectangle instead of annotation rectangle. With this type, I am able to use the data space instead of figure space and everything is fine.

Sensorinput = rand(100,6);
Naminginput = {'a' 'b' 'c' 'd' 'e' 'f'};
sampledExperiment = [10, 10, 0;
                     30, 10, 1;
                     50, 10, 0;
                     70, 10, 1];
experimentnaming = {0, 'classA';
                    1, 'classB'};
samplerate = 10;

h = figure;
for index = 1:1:length(Sensorinput(1,:))
    tempplot = subplot(length(Sensorinput(1,:)),1,index);
    plot(Sensorinput(:,index));
    title(Naminginput(index));
    pos = get (tempplot, 'position')
    step = pos(3)/length(Sensorinput(:,index));

    for index=1:1:length(sampledExperiment)        
        rectangle('Position',[sampledExperiment(index,1),0,sampledExperiment(index,2),1]);
        y  = ylim;
        for namingindex=1:1:length(experimentnaming(:,1))
            if experimentnaming{namingindex,1}==sampledExperiment(index,3)                    
                text(sampledExperiment(index,1)+0.5*sampledExperiment(index,2), y(2),experimentnaming(namingindex,2),'rotation',90);
            end
        end            
    end        
end

I also mixed up the data space with the figure space while plotting the text.

works as expected

Upvotes: 1

Tasos Papastylianou
Tasos Papastylianou

Reputation: 22225

Thanks for clarifying with a working example. Here's another simpler / more visually pleasing way to do it using the area function.

Sensor = struct ('input', num2cell (rand (6, 100), 2), ...
                 'name',  {'a'; 'b'; 'c'; 'd'; 'e'; 'f'});
Experiment = struct ('samplestart', { 10     ,  30     ,  50     ,  70}, ...
                     'samplewidth', { 10     ,  10     ,  10     ,  10}, ...
                     'classindex',  { 0      ,  1      ,  0      ,  1 });

ClassNames     = {'classA', 'classB'};
ClassColours   = {[1.0, 0.8, 0.8], [0.8, 0.8, 1.0]};

NumPlots = length (Sensor);
for n = 1 : NumPlots
  subplot(NumPlots, 1, n); hold on;
  for m = Experiment
    Hndl = area ([m.samplestart, m.samplestart + m.samplewidth], [1, 1]);
    set (Hndl, 'facecolor', ClassColours{m.classindex + 1});
    Hndl = text (m.samplestart+2, 1.2, ClassNames{m.classindex+1});
  end
  plot ([1:100], Sensor(n).input, 'k', 'linewidth', 2);
  text (-7.5, -0.25, Sensor(n).name, 'fontsize', 16, 'fontweight', 'bold');
end

enter image description here

Upvotes: 3

Related Questions