Reputation: 33
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
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.
Upvotes: 1
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
Upvotes: 3