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

 Respuesta aceptada

Star Strider
Star Strider el 11 de En. de 2018
Editada: Star Strider el 11 de En. de 2018
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 comentarios

Julia de Lange
Julia de Lange el 11 de En. de 2018
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 el 11 de En. de 2018
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 el 11 de En. de 2018
Can you please walk me through what this line does?
zci = @(v) find(v(:).*circshift(v(:), [-1 0]) <= 0)
Star Strider
Star Strider el 11 de En. de 2018
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 el 11 de En. de 2018
Amazing! Thank you so much.
How would I edit the function so that it is only outputting the points between t1 < Time < t2?
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 el 12 de En. de 2018
This code works beautifully! Thank you!
Star Strider
Star Strider el 12 de En. de 2018
As always, my pleasure!
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)))
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 el 12 de En. de 2018
worked, thank you!
Star Strider
Star Strider el 12 de En. de 2018
As always, my pleasure!

Iniciar sesión para comentar.

Más respuestas (1)

SRT HellKitty
SRT HellKitty el 11 de En. de 2018
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 comentarios

Julia de Lange
Julia de Lange el 11 de En. de 2018
Editada: Julia de Lange el 11 de En. de 2018
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.
If voltage is exactly 1.4147 another time in the data, do the logical indexing with respect to time
Peaks = time (Voltage == 1.4147)

Iniciar sesión para comentar.

Etiquetas

Preguntada:

el 11 de En. de 2018

Comentada:

el 12 de En. de 2018

Community Treasure Hunt

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

Start Hunting!

Translated by