How to create plots for special areas of an array?

1 view (last 30 days)
Dear people,
I have a plot like this:
I want to plot each of the four waves separately. Of course I could just divide the whole length by 4 but then there would still be the noise from between the big waves. I tried to create a new array where all values smaller than 0.03 are deleted. But then I also delete those values of the big waves as well. Does anybody has an idea how to solve this? Thank you very much:)
  5 Comments
jonas
jonas on 12 Sep 2018
Edited: jonas on 12 Sep 2018
You could calculate a moving std and remove the segments with the lower variation. Could you upload the data? Are there always four distinct waves?
Stwiwi
Stwiwi on 17 Sep 2018
Yeah there are always four waves. I attached three data files. Always with four waves but with different lengths and values.

Sign in to comment.

Accepted Answer

Star Strider
Star Strider on 13 Sep 2018
This is perfect for the findchangepts (link) function, introduced in R2016a.
The Code
D = load('005a_100Hz.mat');
Ch9 = D.Channel_9_Data;
tv = D.Channel_1_Data; % Time Vector
[lpt,rsd] = findchangepts(Ch9, 'Statistic','rms', 'MaxNumChanges',8);
for k1 = 1:2:numel(lpt)-1
sig_seg{(k1+1)/2,1} = Ch9(lpt(k1):lpt(k1+1)); % Signal Values At Each Segment
sig_seg{(k1+1)/2,2} = lpt(k1):lpt(k1+1); % Index Range
end
vl = bsxfun(@times, ones(numel(lpt), 2), [min(Ch9) max(Ch9)]); % Create Vertical Lines For ‘figure(1)’
figure(1)
plot(tv, Ch9)
hold on
plot([tv(lpt),tv(lpt)]', vl', '-r', 'LineWidth',1.5)
hold off
grid
figure(2)
for k1 = 1:size(sig_seg,1)
subplot(size(sig_seg,1), 1, k1)
plot(tv(sig_seg{k1,2}), sig_seg{k1,1})
xlabel('Time (s)')
grid
end
The Plots
  3 Comments
Stwiwi
Stwiwi on 17 Sep 2018
Unfortunately this method wont work for the attached data file. Probably because of all the outliers? Any idea how to solve this? That would be great!

Sign in to comment.

More Answers (2)

Image Analyst
Image Analyst on 12 Sep 2018
What I would do is to scan the signal with a filter to detect the large variations zones, like with movmax(), imdilate(), stdfilt() or similar. Then I'd threshold to find the "quiet" low signal areas. Then I'd find the centroid of those zones, assuming you want to split the signal in the middle of the quiet zones, with the regionprops() function (in the Image Processing Toolbox). I have done this exact thing for a nearly identical signal someone had a couple of years ago. Attach your data if you want any more help.

Stwiwi
Stwiwi on 13 Sep 2018
Ok I have attached one of the Data files and my code so far:
Ord = 6;
f_cf = 5;
f_s = 100;
[b_low, a_low] = butter(Ord,f_cf/(0.5*f_s),'low');
files = dir('*.mat');
for t=1:length(files)
load([files(t).name]);
% Filter Data and write in Workspace
ForceX = filtfilt(b_low,a_low,detrend(Channel_19_Data));
ForceY = filtfilt(b_low,a_low,detrend(Channel_20_Data));
ForceZ = filtfilt(b_low,a_low,detrend(Channel_21_Data)*-1);
USS = detrend(Channel_9_Data*-1);
time = (Channel_1_Data);
end
In the for loop i then go in a function which plots every test and saves it, but I think this code should be enough because I attached only one data file. When I plot USS it shows the plot from my original question. Does that help?

Community Treasure Hunt

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

Start Hunting!