Findpeaks: find the interpolation points for the width with the x axis
4 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Hi,
I am using the function "findpeaks" to find the peaks and their widths for a given signal.
It works very nice, but I would like to get more information for the widths: in particular, the interpolation points in respect to the x-axis that, in my case, is time. I would like to know at what point in time does a width computation starts, and the point in time when it ends.
For example, in the screenshot below, I would like to get the two x values of the yellow width (which for some reasons that I ignore read as the same values now, 43.89).
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/301488/image.jpeg)
0 comentarios
Respuestas (1)
Tommy
el 26 de Mayo de 2020
Editada: Tommy
el 26 de Mayo de 2020
After you call findpeaks, you could obtain a handle to the current axes, find the handle(s) to the yellow horizontal line(s) which indicate the widths, and pull out the XData.
findpeaks(data, 'Annotate', 'Extents')
ax = gca;
widthHandle = findobj(ax, 'Tag', 'HalfProminenceWidth');
widthLoc = [widthHandle.XData(1:3:end)', widthHandle.XData(2:3:end)'];
For the examples I tested, findobj returned just one handle, and the XData was formatted like [left1, right1, NaN, left2, right2, NaN, ...]. It's possible that this may not always be the case, so the above code may not always work, but you should be able to find the locations somehow using the same idea. Note that the tag will be 'HalfHeightWidth' if you tell findpeaks to use 'halfheight' as the 'WidthReference'.
You can also call findpeaks a second time, after your first call, this time requesting output arguments. When you request outputs, findpeaks doesn't plot anything. You could then locate where each width, situated at the half prominence, crosses your data just before and just after reaching the location of the peak. Something like this:
findpeaks(data, 'Annotate', 'Extents')
[peaks,locs,widths,prominence] = findpeaks(data);
widthLoc = nan(numel(peaks),2);
for ii = 1:numel(peaks)
y = peaks(ii) - (prominence(ii)/2); % height based on half prominence
crossLoc = find(diff(sign(data-y)))+1; % rough estimates of all crossings
[~, closestLeft] = find(crossLoc < locs(ii),1); % last crossing before locs(ii)
leftLoc = crossLoc(closestLeft);
x = [leftLoc-1 leftLoc+1]; % assuming actual crossing is between leftLoc-1 and leftLoc+1
widthLoc(ii,1) = interp1(data(x), x, y);
[~, closestRight] = find(crossLoc > locs(ii),1); % first crossing after locs(ii)
rightLoc = crossLoc(closestRight);
x = [rightLoc-1 rightLoc+1]; % similar assumption as above
widthLoc(ii,2) = interp1(data(x), x, y);
% alternatively:
% widthLoc(ii,2) = widthLoc(ii,1) + widths(ii);
end
I highly doubt this is anywhere near as rigorous as the actual code within findpeaks, but maybe it will help you get started.
0 comentarios
Ver también
Categorías
Más información sobre Parametric Spectral Estimation en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!