How to automatically shift a graph back

Hello,
So I have multiple graphs which are out of sync to say.
I do not have the signal processing toolbox so I am forced to do this manually, but what I want is for the largest peak in a graph to be synced up with all the other graphs I will be working with.
I have this code at the very top which only records the x-axis location of the largest peak in plot #1:
offset = time(find(y == max(y)));
I then have this code where I tried to change the x-axis myself based on the offset factor as shown below.
This is what every other plot other than #1 get flagged for.
%If the peak is found to not equal the same x-axis array location than flag AND if the second peak is further to the right than max peak from plot #1 then get flagged
if offset ~= time(find(y == max(y))) && time(find(y == max(y))) - offset > 0
offsetFactor = time(find(y == max(y))) - offset;
time = time - offsetFactor;
elseif offset ~= time(find(y == max(y))) && time(find(y == max(y))) - offset < 0
offsetFactor = time(find(y == max(y))) - offset;
time = time + offsetFactor;
end
Sadly this did not work.
In simple terms, all I want to do is sync all the rest of my plots up to where the max peak for the plot #1 is... if that makes any sense.
I've attached a picture below to show what I want.

9 commentaires

Adam Danz
Adam Danz le 15 Nov 2019
Try a cross correlation between the two signals in order to measure the lag of sig 2 relative to sig 1.
Nom
Nom le 15 Nov 2019
I don't have the signal processing toolbox to do this :(
Adam Danz
Adam Danz le 15 Nov 2019
Modifié(e) : Adam Danz le 15 Nov 2019
Turn that frown upside down because xcorr doesn't require the sig proc toolbox in recent releases :)
>> xcorr(time,time)
To use 'xcorr', the following product must be licensed, installed, and enabled:
Signal Processing Toolbox
I sadly get this error when I try to just run it.
Adam Danz
Adam Danz le 15 Nov 2019
Modifié(e) : Adam Danz le 15 Nov 2019
Hmmmm when I check for the required Matlab products for xcorr, it doesn't list the Sig Proc Toolbox. It just lists Matlab.
I see.... in the 2017b documentation (your version), xcorr() is only provided in the Sig Proc TB. But in the current documentation, xcorr() is provided with the basic Matlab package.
Nom
Nom le 15 Nov 2019
That's unfortunate, the smile turns back into a frown lol.
Adam Danz
Adam Danz le 15 Nov 2019
Modifié(e) : Adam Danz le 15 Nov 2019
You could set up a loop that circularly shifts signal #2 one unit at a time and computes the correlation between both signals on each iteration. Then you just need to locate the max correlation. It's index value is the lag between the two signals that maximizes the correlation.
Look into these functions:
  • circshift()
  • corr()
  • corrcoef()
Steven Lord
Steven Lord le 15 Nov 2019
xcorr and xcov are included in MATLAB as of release R2019a.
Adam Danz
Adam Danz le 15 Nov 2019
Thanks, Steven.
Just wanted to add that they were provided in the Signal Processing Toolbox prior to that (since before 2006).

Connectez-vous pour commenter.

 Réponse acceptée

Adam Danz
Adam Danz le 15 Nov 2019
Modifié(e) : Adam Danz le 15 Nov 2019
If you don't have access to xcorr() you can easily set up a loop the circularly shifts signal-2 one unit at a time and computes the correlation between signal-1 and shifted sig-2 on each iteration. Then you just have to find the index of the max correlation which determines how many units you need to counter-shift sig2.
This uses corr() which requires the Stats and Machine Learning toolbox.
Here's a demo
sig1 = sin(0:pi/8:6*pi).*linspace(.2,1.5,49);
sig2 = [zeros(1,8), sig1(1:end-8)];
clf()
subplot(2,1,1)
plot(sig1, 'k-')
hold on
plot(sig2, 'r--')
title('Raw data')
n = numel(sig2);
c = zeros(1,n);
for i = 1:n
temp = circshift(sig2,i,2); %for row-vector data
c(i) = corr(sig1(:),temp(:));
end
% Find max corr index
[~, maxIdx] = max(c);
% Shift sig2 by -maxIdx units
sig2Shift = circshift(sig2, -maxIdx, 2);
% plot
subplot(2,1,2)
plot(sig1, 'k-')
hold on
plot(sig2Shift,'r--')
title('sig2 shifted')

4 commentaires

Nom
Nom le 15 Nov 2019
Modifié(e) : Nom le 15 Nov 2019
EDIT:
Nevermind I managed to get it working, ignore what I wrote below, this code you wrote works flawlessly, I can't thank you enough Adam!
Thank you so much for this great example Adam.
I'm just having a small problem:
This code definetely works when I omit the x-axis ( just using plot(y) ) that I have for my graphs and it looks amazing thank you so much for this.
However when I plot when my x-axis included ( plot(x,y) ) it just goes back to an unshifted graph. I know this probably is a really simple fix and I'm overlooking something but I just can't for the life of me figure it out
Adam Danz
Adam Danz le 15 Nov 2019
Modifié(e) : Adam Danz le 15 Nov 2019
Glad I could help!
Looks like you figured out that you must circularly shift the x-data too when plotting.
% Shift sig2 by -maxIdx units
sig2Shift = circshift(sig2, -maxIdx, 2); % for row vectors
xShift = circshift(x, -maxIdx, 2); % for row vectors
Nom
Nom le 15 Nov 2019
Modifié(e) : Nom le 15 Nov 2019
EDIT: Sorry for the stupid question, I just substracted the x-value of the peak from all my x-axis values so in this case
newX = x - 10
On this same note of using circshift.
Is there a way I can shift the first peak to be the 0 on the axis?
Let's say the location of the start of the peak is 10 on the x-axis,
I wrote the code below to shift the data 10 units to the left so that the start of the peak can be 0.
test123 = circshift(x',-10)';
However this does not shift the x-axis and then leaves a horizontal line across my plot because the data is not organized
You could used [pks,locs] = findpeaks(data) to get locs, the location of each peak. That algorithm may require some experimentation with the optional input parameters to optimally find your peaks. Once you have the location of the first peak, let's say it's 11, you can circularly shift the x and y values by -11 so that the 1st peak starts at 0. It would look something like this
[pks,locs] = findpeaks(data);
newX = cirshift(x, -locs(1));
newY = cirshift(y, -locs(1));
plot(newX, newY)
Note that this will not trim any of your data. It will merely shift the entire seqence of values, circularly. If there is a flat line in your data, it will remain in your data at a different position.
If you'd like to get rid of all data prior to the first peak,
[pks,locs] = findpeaks(data);
x(1:locs(1)) = [];
y(1:locs(1)) = [];
plot(x, y)

Connectez-vous pour commenter.

Plus de réponses (0)

Produits

Version

R2017b

Community Treasure Hunt

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

Start Hunting!

Translated by