如何在MATLAB中平滑一个图?

时间:2009-10-04 09:03:34

标签: matlab plot smoothing curvesmoothing

我在图表上绘制了大约9000个点:

[Full resolution]

alt text

实际上,情节并不像我希望的那样顺畅。 是否有某种方法可以将图表平滑到所需的程度?

或某种形式的阈值处理,以便我可以选择性地平滑过于颠簸的部分?

我不确定但可以fast-fourier-transform帮助吗?

5 个答案:

答案 0 :(得分:30)

如果您有曲线拟合工具箱,则可以使用smooth功能。默认方法是大小为5的移动平均值(方法可以更改)。一个例子:

% some noisy signal
Fs = 200; f = 5;
t = 0:1/Fs:1-1/Fs;
y = sin(2*pi*f*t) + 0.6*randn(size(t));
subplot(411)
plot(y), title('Noisy signal')

% smoothed signal
subplot(412)
plot( smooth(y, 5, 'moving') ), title('smooth')
ylim([-2 2])

如果没有,您可以使用核心MATLAB中的filter函数使用您自己的窗口函数:

% equivalent to a moving average window
wndwSize = 5;
h = ones(1,wndwSize)/wndwSize;
subplot(413)
plot( filter(h, 1, y) ), title('filter + square window')

% Guassian
h = pdf('Normal',-floor(wndwSize/2):floor(wndwSize/2),0,1);
subplot(414)
plot( filter(h, 1, y) ), title('filter + Guassian window')

screenshot

答案 1 :(得分:17)

一种简单的(临时)方式是在每个点与其邻居进行加权平均(可由alpha调整):

data(2:n-1) = alpha*data(2:n-1) + (1-alpha)*0.5*(data(1:n-2)+data(3:n))

或其某些变体。是的,为了更复杂,您可以先傅里叶变换数据,然后切断高频。类似的东西:

f = fft(data)
f(n/2+1-20:n/2+20) = zeros(40,1)
smoothed = real(ifft(f))

这会削减最高的20个频率。小心地将它们对称地剪切掉,否则逆变换不再是真实的。您需要仔细选择适当平滑级别的截止频率。这是一种非常简单的滤波(频域中的盒式滤波),因此如果失真是不可接受的,您可以尝试轻轻衰减高阶频率。

答案 2 :(得分:5)

FFT并不是一个坏主意,但在这里可能有些过分。运行或移动平均值通常会导致较差的结果,除了迟到的作业(和白噪声)之外,应该避免使用。

我使用Savitzky-Golay过滤(在Matlab中使用sgolayfilt(...))。这将为您提供最佳效果 - 一些局部平滑,同时保持曲线的形状。

-Paul

答案 3 :(得分:3)

有时你应该避免使用移动平均线,因为它对异常值不稳健。在这些情况下,移动中位数是优选的。

答案 4 :(得分:1)

我首先尝试在多个点上显示运行平均值,例如5或10.这样,值中的单个差异只会对图形产生一点影响。当然,这取决于您需要图表的准确程度。