Apply average smoothing to data from text file?
Show older comments
I have tried looking up various way to take my data from a text file and apply a smoothing/moving average filter (without a loop), but NOTHING I do seems to work. I may be completely approaching this wrong, but any help in the right direction would be appreciated!
The file I am working with is attached: SN_d_tot_V2.txt
This is my latest attempt, and while it finally gives me a plot display, it doesn't give me the original data or the smoothed data:
if true
ssnmatrix = dlmread('SN_d_tot_V2.txt'); %data has been truncated to only show 1849-2015
Q = size(ssnmatrix);
nrows = Q(1);
ncolumns = Q(2);
n = 365/2;
ssnave = ssnraw;
ssnave = ssnave/(2*n+1);
% pick out the two relevant columns
decyear = ssnmatrix(:,4);
ssnraw = ssnmatrix(:,5);
% attempt to create filter coefficients
a = 1;
b = [2 1];
%smooth data and plot
y = filter(b,a,ssnave);
t = 1:length(ssnave);
plot(t,decyear,ssnraw,ssnave)
end
Could anyone possible explain what I'm doing wrong? I simply want to smooth the data and get my plot!
3 Comments
Zoe Zontos
on 9 Oct 2016
Star Strider
on 9 Oct 2016
What do you want to do with your signal?
Are there frequency components you want to filter out?
Moving average filters are rarely a good choice for signal processing.
Zoe Zontos
on 9 Oct 2016
Edited: Zoe Zontos
on 9 Oct 2016
Accepted Answer
More Answers (3)
Star Strider
on 10 Oct 2016
Edited: Star Strider
on 11 Oct 2016
My filter approach was correct. It works to filter out the noise and smooth the signal. Also, the 11-year period is obvious if you plot it as a period and not as frequency.
The Code:
d = load('Zoe Zontos SN_d_tot_V2.txt');
t = d(:,4); % Time
sn = d(:,5); % Sunspot Numbers
L = size(sn,1);
tsts = [mean(diff(t)) std(diff(t)) min(t) max(t)];
figure(1)
plot(t, sn)
grid
Ts = tsts(1); % Sampling Interval (Approximate)
Fs = 1/Ts; % Sampling Frequency (Appriximate)
Fn = Fs/2; % Nyquist Frequency (Approximate)
FTsn = fft(sn)/L; % Fourier Transform
Fv = linspace(0, 1, fix(L/2)+1)*Fn; % Frequency Vector
Iv = 1:length(Fv); % Index Vector
% % Fvi = [NaN 1./Fv(2:end)];
Wp = 1/Fn; % Normalised Passband
Ws = 1.5/Fn; % Normalised Stopband
Rp = 20; % Passband Ripple
Rs = 40; % Stopband Ripple
[n,Wn] = buttord(Wp,Ws,Rp,Rs); % Filter Order
[b,a] = butter(n,Wn); % Filter Transfer Function Coefficients
[sos,g] = tf2sos(b,a); % Second-Order-Section For Stability
snf = filtfilt(sos,g,sn); % Phase-Neutral Filtering
figure(3)
freqz(sos) % Bode Plot
figure(2)
semilogy(Fv, abs(FTsn(Iv))*2)
grid
axis([0 25 ylim])
xlabel('Frequency (Y)')
figure(4)
plot(t, sn)
hold on
plot(t, snf, '-r', 'LineWidth',2)
hold off
grid
FTsnf = fft(snf)/L; % Fourier Transform Of Filtered Signal
[sn_max,max_idx] = max(abs(FTsnf(Iv(2:end)))*2);
figure(5)
plot(1./Fv, abs(FTsnf(Iv))*2)
grid
axis([0 15 0 60])
xlabel('Period (Years/Cycle)')
text(1./Fv(max_idx+1), sn_max, sprintf('Mean Number %.2f\nMean Period %.2f years', sn_max, 1./Fv(max_idx+1)), 'HorizontalALignment','center', 'VerticalAlignment','bottom')
The Plots:


EDIT — Corrected units of x-axis label to ‘Years/Cycle’ in second plot figure and code.
Image Analyst
on 9 Oct 2016
You forgot to attach 'SN_d_tot_V2.txt', in case people want to test their code. How do you want to smooth? Personally I'd use conv:
smoothed = conv(ssnraw, ones(1,3)/3, 'same');
But there are other options like different window sizes, sgolayfilt(), etc.
1 Comment
Zoe Zontos
on 9 Oct 2016
Edited: Zoe Zontos
on 9 Oct 2016
Guillaume
on 9 Oct 2016
b = (1/windowSize)*ones(1,windowSize);
All values of b must be equal and their product must be 1 for it to be a moving average filter.
Categories
Find more on Smoothing and Denoising in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!



