find peaks and distance between the x axis
15 次查看(过去 30 天)
显示 更早的评论
i want to calculate the distance between one molecule and the next molecule.
i have written the following code
%load the data from excel
x=xlsread('final.xlsx','Sheet1','A:A');
y=xlsread('final.xlsx','Sheet1','B:B');
findpeaks(x,y)
z=plot(x,y);
% %distance between the peaks x axis
distances=mean(diff(peaks))
its not taking the function findpeaks. the error is Error using findpeaks
Expected X to be increasing valued.
Error in findpeaks>parse_inputs (line 215)
validateattributes(Xin,{'double'},{'real','finite','vector','increasing'},'findpeaks','X');
Error in findpeaks (line 134)
= parse_inputs(Yin,varargin{:});
Error in untitled2 (line 9)
findpeaks(x,y)
0 个评论
回答(4 个)
dpb
2019-6-1
编辑:dpb
2019-6-2
%load the data from excel
xy=xlsread('final.xlsx'); % read the sheet only once
x=xy(:,1); y=xy(:,2); % make local variables if wish...
clear xy % not keep two copies of everything hanging around
hL=plot(x,y); % plot first to visualize the data to understand
The error is quite clear -- your data aren't stored in the file in order of increasing x variable which is a requirement for findpeaks.
Now, whether this is a required condition for the data to make sense or not is something we don't know--we "know nuthink'!" about the data iteself so only you can determine that.
IF (the proverbial "big if") the data can be reorganized, then
[x,is]=sort(x);
y=y(is);
[pks,locs]=findpeaks(y,x);
should return the info you're looking for. Of course, you'll have to ensure that sorting the data by the x variable doesn't destroy what it is your data mean and also determine whether the default peak-finding sensitivity in the function is ok, but we can't answer any of those issues without knowing far more than just the error given.
But, we can determine why the error occurred; we just don't know if the above is a viable solution or not. It's certainly the easiest way to make the error go away but that doesn't mean it's the right solution.
2 个评论
Star Strider
2019-6-1
If ‘x’ has duplicated values, that error would result:
x = linspace(0,3*pi);
x(51) = x(50);
y = sin(3*x);
[pks,locs] = findpeaks(x,y);
and using sort would not fix it.
The unique function would be preferable to sort in this instance, however that leaves the question of what to do about the duplicated values. Once that is decided, the appropriate function to deal with it would likely be accumarray.
dpb
2019-6-1
I expect unique wouldn't be the right idea, SS...that would eliminate those which I'm guessing are needed to define the locations sites--but,again, w/o knowing anything about the data structure, that is purely conjecture indeed, granted.
I hadn't thought of duplicated points though, so that's a good piece of work for the OP if, indeed, is the case.
I've not tested findpeaks for its tolerance; with interp1 i've introduced a +/- 2*eps(x) into the x vector on occasion when needed to bypass the exact match checks to implement step changes or the like. Somesuch trick might also help here--altho depending on what the data actually are representing and how stored, one or the other simpler solutions may be the solution.
dpb
2019-6-2
编辑:dpb
2019-6-2
The position is NOT uniformly increasing -- is for most of the data, but not all...
>> all(diff(data(:,1))>0)
ans =
logical
0
>> sum(diff(data(:,1))<=0)
ans =
7
>> find(diff(data(:,1))<=0)'
ans =
1176 1177 1178 1179 1180 1181 1182
>>
See attached figures that show the pertinent pieces...
So, the question is what does the negative position difference mean and how to treat those pieces of the response? Is position absolute or relative or just what does it represent?
Perhaps one could recompute the position as the absolute difference relative the previous point to produce an ever-increasing position measurement that retains the same relative separation and keep the meaning of the measurement?
Dunno, the answers to those questions, but that's the problem with findpeaks -- it's not lying, the data isn't monotonically increasing in its position mmeasurement as promised.
0 个评论
dpb
2019-6-2
Actually, I reversed the order of arguments when using two in findpeaks in first answer -- the x location is the optional second argument, not the first--the waveform is the first argument always. My bad...just not thinking; following the plot syntax of (x,y).
To deal with the position data as is, just use
xy=xlsread('book1.xlsx'); % again, only need to read the data one time
x=xy(:,1); y=xy(:,2); clear xy % make local variables w/ mnemonic names
[pks,locs]=findpeaks(y,'minpeakheight',30,'minpeakdistance',20); % return peaks and location in array
d=x(locs); % return the positions of the peaks in measured units
dx=diff(x); % the distances between each peak
Observation with the specific data set shows no negative dx so the actual negative position difference doesn't matter for the particular dataset. Whether that would be true in general is pure luck, probably...
0 个评论
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!