downsampling / reducing fft data for log plot

9 ビュー (過去 30 日間)
Bernd
Bernd 2012 年 10 月 30 日
Hello,
I want to plot the data from an fft, however as the source data is very large consequently my fft data consists of one million samples. I want to plot the data in a log-log plot, but of course not all of the samples are necessary.
How can I downsample / reduce the number of samples/frequencies of the fft result while keeping the quality of the plot? If I remove for example every 4th sample it won't have an effect on the high frequencies, but I will lose precious samples on the low frequency range.
Thanks for your help!
To make it a bit more clear: The fft results have a sampling rate of 100Hz: 100Hz, 200Hz, 300Hz,...1e8Hz When I plot the spectrum logarithmically the range between 100 and 1000Hz has 9 samples (ok) between 1000 and 10000Hz has 90 samples (ok) between 10000 and 100000Hz has 900 samples (still ok, starts getting too much) between 1e7 and 1e8Hz has 900000 samples (way too much)
So I want to reduce the number of samples, especially in the higher frequencies, while keeping the low frequencies more intact, as a strong reduction of samples will change the plot significantly.
  2 件のコメント
Walter Roberson
Walter Roberson 2012 年 10 月 30 日
Sorry, I am not clear: when you are referring to samples to be removed, are you referring to the data that is to be fft'd, or are you referring to the results of fft ?
Bernd
Bernd 2012 年 10 月 31 日
Sorry if it was unclear. I meant the samples/frequencies of the fft result. I edited the question to clarify this.

サインインしてコメントする。

回答 (4 件)

MANJUNATH
MANJUNATH 2012 年 10 月 31 日
reduce 'samplesPerTrigger' and try plotting
  1 件のコメント
Bernd
Bernd 2012 年 10 月 31 日
Thanks, but if I understood this correctly this will reduce the samples linearly, which is bad when plotting logarithmically.

サインインしてコメントする。


Wayne King
Wayne King 2012 年 10 月 31 日
編集済み: Wayne King 2012 年 10 月 31 日
If you have the Signal Processing Toolbox, you can use goertzel.m to compute the DFT at specified frequencies. For example:
Fs = 1000;
t = 0:1/Fs:1-1/Fs;
x = cos(2*pi*100*t)+1/2*cos(2*pi*200*t)+1/4*cos(2*pi*300*t);
The indices in the DFT for 100,200, and 300 Hz are 101,201,and 301
idx = [101 201 301];
xdft = goertzel(x,idx);
A better example would be: Resolve the 1.24 kHz and 1.26 kHz components in the following noisy cosine which also has a 10 kHz component. The data is sampled at 32 kHz.
Fs = 32e3; t = 0:1/Fs:2.96;
x = cos(2*pi*t*10e3)+cos(2*pi*t*1.24e3)+cos(2*pi*t*1.26e3)...
+ randn(size(t));
N = (length(x)+1)/2;
f = (Fs/2)/N*(0:N-1); % Generate frequency vector
indxs = find(f>1.2e3 & f<1.3e3); % Find frequencies of interest
X = goertzel(x,indxs);
plot(f(indxs)/1e3,20*log10(abs(X)/length(X)));
title('Mean Squared Spectrum');
xlabel('Frequency (kHz)');
ylabel('Power (dB)');
grid on;
set(gca,'XLim',[f(indxs(1)) f(indxs(end))]/1e3);
where you select a range of frequencies.
You can also just plot a range of frequencies in the fft() output. You don't have to plot the entire output.
  1 件のコメント
Bernd
Bernd 2012 年 10 月 31 日
Thanks for the help, but I don't think this solves the problem, as I don't want to do an fft for specific frequencies, but rather for the full spectrum. Only when plotting the spectrum I want to reduce the number of samples in the high frequencies.
I added an example to my questions, maybe this makes it more clear.

サインインしてコメントする。


Wayne King
Wayne King 2012 年 10 月 31 日
To make it a bit more clear: The fft results have a sampling rate of 100Hz: 100Hz, 200Hz, 300Hz,...1e8Hz When I plot the spectrum logarithmically the range between 100 and 1000Hz has 9 samples (ok) between 1000 and 10000Hz has 90 samples (ok) between 10000 and 100000Hz has 900 samples (still ok, starts getting too much) between 1e7 and 1e8Hz has 900000 samples (way too much)
You do not mean sampling rate. You mean frequency resolution. Specifically, you mean the spacing between DFT bins is 100 Hz.
Have you seen my suggestion of goertzel.m?

Dr. Seis
Dr. Seis 2012 年 10 月 31 日
A possible workaround since you want to compute and retain ALL frequencies, but only plot a subset. You can try plotting a subset of your data so that you keep more low frequency points and ignore more high frequency points by:
N = 1000; % Number of samples you want to plot
f_begin = 1e2; f_end = 1e8;
log10_df = (log10(f_end)-log10(f_begin))/N;
new_f = 10 .^ (log10(f_begin) : log10_df : log10(f_end));
Then plot:
plot(new_f,interp1(OLD_Frequencies_1e2_to_1e8, OLD_Amplitudes_1e2_to_1e8, new_f)
If you don't want to interpolate, then you can either try to find the index associated with the closest matching frequency OR possibly try to take an average of the amplitude data around the matching frequency.

カテゴリ

Help Center および File ExchangeFourier Analysis and Filtering についてさらに検索

製品

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by