How can I match a value on a matlab plot?

I have identified the first peak value in my dataset. I'd like to know the first x-value at the point at which this peak y-value occurs again. Any suggestions? p

 採用された回答

Star Strider
Star Strider 2018 年 1 月 11 日
編集済み: Star Strider 2018 年 1 月 11 日

1 投票

Use the ‘locs’ value:
[pks,locs] = findpeaks(Voltage, 'MinPeakDist',2000, 'NPeaks',1);
peakTimes = Time(locs);
See the plot call in my previous code to demonstrate how to do this.
EDIT
‘I'd like to determine x (time) the next time 1.4147 (y, voltage) occurs.’
This will give all the ‘Voltage’ and ‘Time’ values that equal or exceed the initial peak value:
[D,S,R] = xlsread('Data.xls');
Time = D(:,1);
Voltage = D(:,2);
[pks,locs] = findpeaks(Voltage, 'MinPeakDist',2000, 'NPeaks',1, 'MinPeakHeight',1.2);
VoltageThreshold = Voltage - pks*0.99;
zci = @(v) find(v(:).*circshift(v(:), [-1 0]) <= 0); % Returns Approximate Zero-Crossing Indices Of Argument Vector
zx = zci(VoltageThreshold);
TimeNew = Time(zx); % Time Vector, Voltage >= VoltageThreshold
VoltageNew = Voltage(zx); % Voltage Vector, Voltage >= VoltageThreshold
figure(1)
plot(Time, Voltage)
hold on
plot(Time(locs), Voltage(locs), '+g')
plot(TimeNew, VoltageNew, '+r')
hold off
grid

12 件のコメント

Julia de Lange
Julia de Lange 2018 年 1 月 11 日
I have time (x) plotted versus voltage (y). I have found the first peak to occur at (1.037,1.4147). I'd like to determine x (time) the next time 1.4147 (y, voltage) occurs.
Star Strider
Star Strider 2018 年 1 月 11 日
Please run my code. It will give you the ‘Time’ values at the points where ‘Voltage’ crosses the 1.4147 value, returned in the ‘TimeNew’ and ‘VoltageNew’ vectors. It then plots them.
Julia de Lange
Julia de Lange 2018 年 1 月 11 日
Can you please walk me through what this line does?
zci = @(v) find(v(:).*circshift(v(:), [-1 0]) <= 0)
Star Strider
Star Strider 2018 年 1 月 11 日
Sure.
It is a little utility function that finds the zero-crossings of a data vector. It works by using the circshift function to shift the argument vector one position up (since it transforms the arguments to column vectors), then it multiplies the original and shifted vectors together. Where those adjacent values have the same signs — either positive or negative — the sign of the product will be positive. Where there is a zero-crossing, so that the adjacent values have opposite signs, the product will be negative or zero. The find function returns the indices of the values that are negative or zero, and so are approximately where the zero-crossings occur.
In my code here, I subtract the value you want to find, 1.4147, from the entire vector to create zero-crossings at that value, then use my ‘zci’ function to find their approximate indices.
Julia de Lange
Julia de Lange 2018 年 1 月 11 日
Amazing! Thank you so much.
How would I edit the function so that it is only outputting the points between t1 < Time < t2?
Star Strider
Star Strider 2018 年 1 月 11 日
As always, my pleasure!
Do not edit the function. Define what ‘t1’ and ‘t2’ are, run the function on your entire data vector, and then edit the data.
Example
[D,S,R] = xlsread('Data.xls');
Time = D(:,1);
Voltage = D(:,2);
[pks,locs] = findpeaks(Voltage, 'MinPeakDist',2000, 'NPeaks',1, 'MinPeakHeight',1.2);
VoltageThreshold = Voltage - pks*0.99;
zci = @(v) find(v(:).*circshift(v(:), [-1 0]) <= 0); % Returns Approximate Zero-Crossing Indices Of Argument Vector
zx = zci(VoltageThreshold);
TimeNew = Time(zx); % Time Vector, Voltage >= VoltageThreshold
VoltageNew = Voltage(zx); % Voltage Vector, Voltage >= VoltageThreshold
t1 = 0.9; % Start Time
t2 = 2.1; % End Time
tlimidx = find((Time >= t1) & (Time <= t2)); % Indices of ‘Time’ Between ‘1’ & ‘2’
TimeLimitIndices = zx((zx >= tlimidx(1)) & (zx <= tlimidx(end))); % ‘zx’ Indices Meeting Criteria
figure(1)
plot(Time, Voltage)
hold on
plot(Time(locs), Voltage(locs), '+g')
plot(TimeNew, VoltageNew, '+r')
plot(Time(TimeLimitIndices), Voltage(TimeLimitIndices), 'ms')
hold off
grid
I use find and the index limit range here to define ‘TimeLimitIndices’. The ismember or intersect functions could also work. I did not experiment with them here.
Julia de Lange
Julia de Lange 2018 年 1 月 12 日
This code works beautifully! Thank you!
Star Strider
Star Strider 2018 年 1 月 12 日
As always, my pleasure!
Julia de Lange
Julia de Lange 2018 年 1 月 12 日
The lines below output 4 different time points, and I'd like to specify the last time point to callout and manipulate later on in my code. I do not care about the other ones. Is there a way to automate this process without user input?
tlimidx = find((Time >= t1) & (Time <= t2), 'last');
TimeLimitIndices = zx((zx >= tlimidx(1)) & (zx <= tlimidx(end)))
Star Strider
Star Strider 2018 年 1 月 12 日
Try this:
LastTimeIndex = TimeLimitIndices(end);
That should work.
Note that this returns the index, so the value would be: Time(LastTimeIndex).
Julia de Lange
Julia de Lange 2018 年 1 月 12 日
worked, thank you!
Star Strider
Star Strider 2018 年 1 月 12 日
As always, my pleasure!

サインインしてコメントする。

その他の回答 (1 件)

SRT HellKitty
SRT HellKitty 2018 年 1 月 11 日

0 投票

Say you have data with peaks for the Y-Axis and linear data for the X-Axis
Y = [1:5,1:5,1:5];
X = [1:15];
Now you have 3 peaks in Y, when it equals 5. If you want to know what value of X is when Y is equal to 5 you could do a logical index;
X_at_peaks = X(Y == 5);
That would show that X is 5, 10, and 15 when Y is equal to 5.

2 件のコメント

Julia de Lange
Julia de Lange 2018 年 1 月 11 日
編集済み: Julia de Lange 2018 年 1 月 11 日
Let me give you more details. I have attached my data with one time (x) plotted versus voltage (y). I have found the first peak to occur at (1.037,1.4147). I'd like to determine x (time) the next time 1.4147 (y, voltage) occurs.
SRT HellKitty
SRT HellKitty 2018 年 1 月 11 日
If voltage is exactly 1.4147 another time in the data, do the logical indexing with respect to time
Peaks = time (Voltage == 1.4147)

サインインしてコメントする。

タグ

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by