如何在MATLAB中平滑绘图?

时间:2021-09-05 04:17:15

I have some 9000 points that are plotted on a graph:

我在图上画了9000点

[Full resolution]

(完整的决议)

如何在MATLAB中平滑绘图?

Actually, the plot is not as smooth as I wanted it to be. Is there some way I can smoothen the graph to a required degree?

实际上,情节并不像我想象的那么顺利。有没有什么方法可以让图形达到要求的程度?

Or some form of thresholding so that I can selectively smoothen out the parts that is too bumpy?

或者某种形式的阈值,这样我可以有选择地抚平那些太颠簸的部分?

I am not sure but can fast-fourier-transform help?

我不确定,但是快速傅里叶变换能有帮助吗?

5 个解决方案

#1


17  

A simple (ad hoc) way is to just take a weighted average (tunable by alpha) at each point with its neighbors:

一个简单(特别)的方法是,在每个点与它的左邻右取一个加权平均(可调):

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

or some variation thereof. Yes, to be more sophisticated you can Fourier transform your data first, then cut off the high frequencies. Something like:

或者一些变化。是的,更复杂的是,你可以先对数据进行傅里叶变换,然后切断高频。喜欢的东西:

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

This cuts out the highest 20 frequencies. Be careful to cut them out symmetrically otherwise the inverse transform is no longer real. You need to carefully choose the cutoff frequency for the right level of smoothing. This is a very simple kind of filtering (box filtering in frequency domain), so you can try gently attenuating high order frequencies if the distortion is unacceptable.

这就减少了最高的20个频率。要小心地把它们分开,否则逆变换就不再是实数了。您需要仔细选择合适的平滑度的截止频率。这是一种非常简单的滤波(在频域内进行滤波),所以如果失真是不可接受的,你可以尝试轻轻地衰减高阶频率。

#2


30  

If you have the Curve Fitting Toolbox, you can use the smooth function. The default method is a moving average of size 5 (method can be changed). An example:

如果你有曲线拟合工具箱,你可以使用平滑函数。默认方法是移动平均大小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])

If not, you can use use your own window function using the filter function from core MATLAB:

如果没有,您可以使用从core 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')

如何在MATLAB中平滑绘图?

#3


5  

FFT isn't a bad idea, but it's probably overkill here. Running or moving averages give generally poor results and should be avoided for anything besides late homework (and white noise).

FFT不是一个坏主意,但它可能在这里过度了。跑步或移动的平均成绩通常会导致糟糕的结果,除了迟交的作业(和白噪音)之外,其他任何事情都应该避免。

I'd use Savitzky-Golay filtering (in Matlab sgolayfilt(...)). This will give you the best results for what you are looking for - some local smoothing while maintaining the shape of the curve.

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

-Paul

保罗

#4


3  

Sometimes you should avoid using mobile average as it's not robust to outliers. Mobile median is preferable in those cases.

有时,您应该避免使用移动平均,因为它对异常值不健壮。在这些情况下,移动中位数更可取。

#5


1  

I'd first try to display the running average over a number of points, like 5 or 10. This way, a single discrepancy in the values only have a little impact on the graph. Of course, it depends on how accurate you need the graph to be.

我首先尝试在一些点上显示运行平均值,比如5或10。这样,在值上的单个差异只会对图形产生一点影响。当然,这取决于你需要的图形有多精确。

#1


17  

A simple (ad hoc) way is to just take a weighted average (tunable by alpha) at each point with its neighbors:

一个简单(特别)的方法是,在每个点与它的左邻右取一个加权平均(可调):

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

or some variation thereof. Yes, to be more sophisticated you can Fourier transform your data first, then cut off the high frequencies. Something like:

或者一些变化。是的,更复杂的是,你可以先对数据进行傅里叶变换,然后切断高频。喜欢的东西:

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

This cuts out the highest 20 frequencies. Be careful to cut them out symmetrically otherwise the inverse transform is no longer real. You need to carefully choose the cutoff frequency for the right level of smoothing. This is a very simple kind of filtering (box filtering in frequency domain), so you can try gently attenuating high order frequencies if the distortion is unacceptable.

这就减少了最高的20个频率。要小心地把它们分开,否则逆变换就不再是实数了。您需要仔细选择合适的平滑度的截止频率。这是一种非常简单的滤波(在频域内进行滤波),所以如果失真是不可接受的,你可以尝试轻轻地衰减高阶频率。

#2


30  

If you have the Curve Fitting Toolbox, you can use the smooth function. The default method is a moving average of size 5 (method can be changed). An example:

如果你有曲线拟合工具箱,你可以使用平滑函数。默认方法是移动平均大小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])

If not, you can use use your own window function using the filter function from core MATLAB:

如果没有,您可以使用从core 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')

如何在MATLAB中平滑绘图?

#3


5  

FFT isn't a bad idea, but it's probably overkill here. Running or moving averages give generally poor results and should be avoided for anything besides late homework (and white noise).

FFT不是一个坏主意,但它可能在这里过度了。跑步或移动的平均成绩通常会导致糟糕的结果,除了迟交的作业(和白噪音)之外,其他任何事情都应该避免。

I'd use Savitzky-Golay filtering (in Matlab sgolayfilt(...)). This will give you the best results for what you are looking for - some local smoothing while maintaining the shape of the curve.

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

-Paul

保罗

#4


3  

Sometimes you should avoid using mobile average as it's not robust to outliers. Mobile median is preferable in those cases.

有时,您应该避免使用移动平均,因为它对异常值不健壮。在这些情况下,移动中位数更可取。

#5


1  

I'd first try to display the running average over a number of points, like 5 or 10. This way, a single discrepancy in the values only have a little impact on the graph. Of course, it depends on how accurate you need the graph to be.

我首先尝试在一些点上显示运行平均值,比如5或10。这样,在值上的单个差异只会对图形产生一点影响。当然,这取决于你需要的图形有多精确。