平滑曲线

时间:2015-08-11 14:45:04

标签: matlab plot

下面是我的情节代码。如何使情节更加顺畅。

len1 = [25, 250, 500, 750, 1000];
for k1 = 1:length(len1)
    standard_deviation1(k1) = std(resdphs(1:5000, len1(k1)));
end

f10 = [110, 100, 90, 80, 70];
figure(3),plot(f10, standard_deviation1);xlabel('frequency'); ylabel('standarddev');

enter image description here

1 个答案:

答案 0 :(得分:4)

如评论中所述,您可以先尝试将moving average应用于数据,这会将局部平滑应用于数据中的重叠窗口。但是,为了获得成功,您必须具有更高的点密度才能实现良好的平滑效果。目前,您的绘图只有几个点均匀间隔500个单位,因此移动平均值将显着改变绘图的外观。我很快就会给你看一个例子。

让我们回到手头的方法。首先,在每个点之间应用线性插值以获得更高的点密度。应用线性插值后,可以使用conv应用移动平均操作。但是,将会发生的是,在您的关键点之间将存在不能代表您的问题的人工数据。我还想提一下,这个图是出于美学目的,关键点之间的数据不应该用于任何关键决策。

如果您只是想绘制点数,请考虑不使用plot并使用stem。在任何情况下,使用interp1作为在关键点之间进行插值的基本方法。一旦你这样做,你可以通过卷积应用移动平均值 - 具体来说,使用具有少量滤波器抽头的内核,这些滤波器都具有相同的权重。像5抽头窗口或7抽头窗口就足够了。

使用您在上面声明的变量:

%// 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));

使用上面的数据和上面的代码,我们得到了这个图:

enter image description here

正如您所看到的,在没有插值的情况下对数据应用移动平均值会因分辨率而显着改变数据。如果先应用插值,然后应用移动平均值,您将看到在角平滑的情况下,您可以更好地表示原始数据。请记住,平滑结果开始和结束时的数据将毫无意义,因为您将采用填充为数据的零填充窗口的移动平均值,以使计算起作用。