如 cmets 中所述,您可以先尝试将 moving average 应用于您的数据,从而将局部平滑应用于数据中的重叠窗口。但是,要成功,您必须具有更高的点密度才能实现良好的平滑。目前,您的绘图只有几个以 500 个单位均匀分布的点,因此移动平均线将显着改变绘图的外观。我很快就会给你看一个例子。
让我们回到手头的方法。首先,在每个点之间应用线性插值以获得更高的点密度。应用线性插值后,您可以使用conv 应用移动平均操作。但是,将会发生的是,在您的关键点之间将存在不能代表您的问题的人工数据。我还想提一下,这个图是出于审美目的,关键点之间的数据不应用于任何关键决策。
如果您只是想绘制点,请考虑不使用plot 而是使用stem。在任何情况下,使用interp1 作为在关键点之间进行插值的基本方法。完成此操作后,您可以通过卷积应用移动平均值 - 具体而言,使用具有少量滤波器抽头的内核,这些滤波器抽头均等权重。类似 5-tap 窗口或 7-tap 窗口可能就足够了。
使用您在上面声明的变量:
%// Specify number of total points
num_points = 300;
%// Specify moving average window
move_size = 7;
%// Specify interpolated y coordinates
xpts = linspace(min(f10), max(f10), num_points);
out = interp1(f10, standard_deviation1, xpts, 'linear');
%// Apply moving average
kernel = (1/move_size)*(ones(1,move_size));
out_smooth = conv(out, kernel, 'same');
%// Also apply moving average on the raw data itself for demonstration
out_smooth_raw = conv(standard_deviation1, kernel, 'same');
%// Plot everything
plot(f10, standard_deviation1, f10, out_smooth_raw, 'x-', xpts, out_smooth);
legend('Original Data', 'Smoothed Data - Raw', 'Smoothed Data - Interpolated');
让我们用一些示例数据来做这件事:
f10 = 0 : 500 : 5000;
rng(123); %// Set seed for reproducibility
standard_deviation1 = rand(1,numel(f10));
使用上面的数据和上面的代码,我们得到了这个图:
如您所见,由于分辨率的原因,对数据应用移动平均值而不进行插值会显着改变数据。如果您先应用插值,然后再应用移动平均线,您会发现原始数据的表现更好一些,边角平滑。请记住,平滑结果开始和结束时的数据将毫无意义,因为您将取窗口的移动平均值,并在数据中填充零以允许计算工作。