问题
I want to make a 3d plot of 2d plots of function y where y is the dft of function z with having as axis k(x) w0(y) and amplitude(y)(z), where k is the dft variable in frequency domain and w0 is a changing parameter between 0 and 4*pi/45.
n=(0:255);
x1 = exp(n.*(w1*1j));
x2 = 0.8.*exp(n*((w2-w0)).*1j);
z =hamming(256)*(x1+x2);
y = fft(abs(z))
回答1:
If I'm interpreting your question properly, you wish to have something like this:
The x
axis is the DFT number, the y
axis is a parameter that changes your time-domain signal and z
would be the magnitude of the FFT for each signal.
What you need to do is define a 2D grid of points where x
is the number of FFT points you have... so in your case, that'll be 256 points, and the y
axis defines your varying w0
term from 0 to 4*pi/45
. The structure for this grid will be such that each row defines one DFT result.
For this, use ndgrid for that, and you do it the following way:
max_dft_number = 256;
num_w = 10;
[w0,n] = ndgrid(linspace(0,4*pi/45,num_w), 0:max_dft_number-1);
max_dft_number
determines how many DFT numbers you want to compute. So in your case, that would be 256. You can vary that according to how many DFT numbers you want. num_w
gives you how many w0
points you want between 0 to 4*pi/45
, then linspace gives you a set of linearly spaced points from 0 to 4*pi/45
where we have num_w
of these points. I set it to 10 here to give a good illustration.
Once you have this, simply use X
and Y
and substitute it into your code above. You don't define w1
and w2
, so I'll assume it's constant:
w1 = 0.1; w2 = 0.2;
x1 = exp(n.*(w1*1j)); %// Change - vectorized
x2 = 0.8.*exp(n.*((w2-w0)).*1j); %// Change - vectorized
z = bsxfun(@times,hamming(max_dft_number).', x1+x2); %// Change - make sure hamming window applies over each row
y = abs(fft(z, [], 2)); %// Change - FFT first, then magnitude after. Apply to each row
I had to use bsxfun
to apply the Hamming window on each row of x1 + x2
. Remember, each row is a DFT result for a particular w0
parameter. I also had to transpose hamming(256)
as the default output is a column. bsxfun
in this case with the use of @times
will duplicate the Hamming window coefficients so that every row gets multiplied by the same window. If you provide a matrix to fft
, by default it applies the FFT over each column of a matrix. We don't want that, and we want to apply this to every row, and so you would need to do fft(z,[],2);
to do that.
Now, to finally achieve your desired plot, all you have to do is use the waterfall function, which takes in a set 2D grid coordinates and the corresponding output in the z
direction. It assumes that each row is an individual trace of a 3D function.... just like what you wanted.
So:
waterfall(n, w0, y);
xlabel('DFT number');
ylabel('w0');
zlabel('Magnitude');
colormap([0 0 0]); %// Make plot all black
view(-12,64); %// Adjust view for better look
We get:
来源:https://stackoverflow.com/questions/29322617/how-to-plot-a-3d-graph-of-2d-fft-transformations-with-a-changing-parameter