How to include Annotate extends … in this MATLAB findpeaks?

随声附和 提交于 2020-01-23 18:38:10

问题


I have minimums and maximums in the output now (Fig.1) but I would like to get labels (Fig. 2) for sorted maximums (tallest get 1, ...) and similarly for minimums (lowest gets 1). I can do the output of Fig. 1 by the following but I cannot integrate those annotations to the function

close all; clear all; clc; 
% https://se.mathworks.com/help/signal/ref/findpeaks.html
% http://stackoverflow.com/a/26837689/54964
x = linspace(0,1,1000);

Pos = [1 2 3 5 7 8]/10;
Hgt = [4 4 2 2 2 3];
Wdt = [3 8 4 3 4 6]/100;

for n = 1:length(Pos)
    Gauss(n,:) =  Hgt(n)*exp(-((x - Pos(n))/Wdt(n)).^2);
end

PeakSig = sum(Gauss) - exp(sum(Gauss))/10;

plot(x, PeakSig); 
hold on; 

[p l]=findpeaks(PeakSig); %,x); %,'Annotate','extents','WidthReference','halfheight')
plot(x(l), p, 'ko', 'MarkerFaceColor', 'g');  

[pn ln]=findpeaks(-PeakSig); %,x); %,'Annotate','extents','WidthReference','halfheight')
plot(x(ln), -pn, 'ko', 'MarkerFaceColor', 'r'); 
title('Signal Peak Widths')

To just append 'Annotate','extents','WidthReference','halfheight') to [p l]=findpeaks(...) is not working in the application etc the following apparently because the proceeding line plot(x(l), p, 'ko', 'MarkerFaceColor', 'g'); does not understand the extra content made by the one-liner in the corresponding variables

[p l]=findpeaks(PeakSig,'Annotate','extents','WidthReference','halfheight')
[p l]=findpeaks(PeakSig, x, 'Annotate','extents','WidthReference','halfheight')

Fig. 1 Current output without those annotations, Fig. 2 Expected output but with notes of maximums and minimums

MATLAB: 2016b
OS: Debian 8.5 64 bit
Hardware: Asus Zenbook UX303UA


回答1:


Here is one way to to this:

x = linspace(0,1,1000);
Pos = [1 2 3 5 7 8]/10;
Hgt = [4 4 2 2 2 3];
Wdt = [3 8 4 3 4 6]/100;
Gauss = zeros(numel(Pos),numel(x));
for n = 1:numel(Pos)
    Gauss(n,:) =  Hgt(n)*exp(-((x - Pos(n))/Wdt(n)).^2);
end
PeakSig = sum(Gauss) - exp(sum(Gauss))/10;

% get the peaks:
[p,xmax] = findpeaks(PeakSig,x);
maxsrt = sortrows([xmax;p].',-2);
[pn,xmin] = findpeaks(-PeakSig,x);
minsrt = sortrows([xmin;-pn].',2);

% plotting:
blue = [0 0.447 0.741];
plot(x,PeakSig,xmax,p+0.2,'v','MarkerFaceColor',blue,'MarkerEdgeColor',blue);
% you can comment the line above and uncomment the line below, if you
% prefer:
% findpeaks(PeakSig,x,'Annotate','peaks');
text(maxsrt(:,1),maxsrt(:,2)+0.2,num2str((1:numel(p)).'),'FontSize',14,...
    'VerticalAlignment','bottom','HorizontalAlignment','center')
ylim([-10 3]);
grid on
hold on
plot(xmin,-pn-0.2,'^','MarkerFaceColor',blue,'MarkerEdgeColor',blue);
hold off
text(minsrt(:,1),minsrt(:,2)-0.2,num2str((1:numel(pn)).'),'FontSize',14,...
    'VerticalAlignment','top','HorizontalAlignment','center')
title('Signal Peak Widths')




回答2:


And here is another way to do this, using gscatter. Instead of calling plot twice (and maybe more if other annotations are needed), you concat all the positions (x-y) and type of annotations to one array (pks bellow), and plot them all at once by thier type (i.e. group) with gscatter:

x = linspace(0,1,1000);
Pos = [1 2 3 5 7 8]/10;
Hgt = [4 4 2 2 2 3];
Wdt = [3 8 4 3 4 6]/100;
Gauss = zeros(numel(Pos),numel(x));
for n = 1:numel(Pos)
    Gauss(n,:) =  Hgt(n)*exp(-((x - Pos(n))/Wdt(n)).^2);
end
PeakSig = sum(Gauss) - exp(sum(Gauss))/10;

% get the peaks:
[p,xmax] = findpeaks(PeakSig,x);
maxsrt = sortrows([xmax;p].',-2);
[pn,xmin] = findpeaks(-PeakSig,x);
minsrt = sortrows([xmin;-pn].',2);

% plotting:
pks = [[xmin xmax];[-pn-0.2 p+0.2];[zeros(1,numel(pn)) ones(1,numel(p))]].';
blue = [0 0.447 0.741];
ax = axes;
plot(ax,x,PeakSig)
hold on
gscatter(pks(:,1),pks(:,2),pks(:,3),blue,'^v')
hold off
ax.Children(1).MarkerFaceColor = blue;
ax.Children(2).MarkerFaceColor = blue;
text(maxsrt(:,1),maxsrt(:,2)+0.2,num2str((1:numel(p)).'),'FontSize',14,...
    'VerticalAlignment','bottom','HorizontalAlignment','center')
text(minsrt(:,1),minsrt(:,2)-0.2,num2str((1:numel(pn)).'),'FontSize',14,...
    'VerticalAlignment','top','HorizontalAlignment','center')
ylim([-10 3]);
legend off
grid on
title('Signal Peak Widths')

the result is exactly the same, but this is more short and maybe more elegant.



来源:https://stackoverflow.com/questions/40075612/how-to-include-annotate-extends-in-this-matlab-findpeaks

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