ni.com is currently experiencing unexpected issues.
Some services may be unavailable at this time.
09-24-2012 02:58 PM
Development Environment:
* Microsoft Visual Studio 2010 Pro
* C# Language
* National Instruments Measurement Studio 2012
Summary of Question:
* I'm plotting data from a Fast Fouirer Tranform (FFT)
* The scale on the X-Axis is currently the number of BINS in the FFT.
* I want the scale on the X-Axis to be the Frequency (which should be from 0 Hz to 1000 Hz)
More Thoughts on the Question:
* Lets say the number of data-samples I'm collecting is 4096 at a frequency of 2000 samples/second.
* This results in an FFT that has 2048 BINS and should represent frequencies from 0 to 1000 Hz.
* If I just plot the data as-is...I get an X-Axis from 0 to 2048.
* There is a scaling factor that I could multiply X by to get the proper X values. (I have that)
* The problem is the X-Values for the plot are the ARRAY INDICES...and those obviously have to be whole numbers.
Code I'm Using...simplified with irrelevant thigns left out:
void PlotFFT(System.Numerics.Complex[] FFT_Result_Bins)
{
// Create an object that describes the properties of how the plot should be created.
ComplexDataPart complexDataPart = ComplexDataPart.Real;
ComplexWaveformPlotOptions complexPlotOptions = new ComplexWaveformPlotOptions(
ComplexWaveformPlotDisplayMode.Samples,
ComplexWaveformPlotScaleMode.Scaled, complexDataPart);
const int DataSamplingRate = 2000;
const int DiscernableFrequency = DataSamplingRate / 2;
int NumberOfBins = FFT_Result_Bins.Length;
double HzPerBin = DiscernableFrequency / NumberOfBins;
// Generate an array of doubles from the FFT_Result_Bins.
var dataPoints = new ComplexDouble[NumberOfBins];
for (int x = 0; x < NumberOfBins; x++)
{
dataPoints[x].Real = FFT_Result_Bins[x].Real;
dataPoints[x].Imaginary = FFT_Result_Bins[x].Imaginary;
}
// Create a WaveForm data strcuture/object from the array of data (doubles).
ComplexWaveform<ComplexDouble> waveform = ComplexWaveform<ComplexDouble>.FromArray1D(dataPoints);
// Plot the graph using a separate thread.
this.BeginInvoke(new MethodInvoker(delegate()
{waveformGraphFreqDomain.PlotComplexWaveform<ComplexDouble>(waveform, complexPlotOptions);}));
}
Thanks for any help!
gw
09-25-2012 02:33 PM
Hello Jabadoodle,
Thank you for the thorough post.
Setting up your graph, with ComplexWaveformPlotDisplayMode set for samples, and plotting a waveform with 2048 data points would work as you are seeing.
I haven't configured any complex data to test this with; however based on the PlotComplexWaveform help example, you should be able to set the DisplayMode to Time and then configure the X-Axis to not display the samples. This may be configurable to show what you want. Have you tried that? What have been the results?
ComplexWaveform<ComplexDouble> waveform; ComplexWaveformPlotOptions options = new ComplexWaveformPlotOptions(ComplexWaveformPlotDisplayMode.Time, ComplexWaveformPlotScaleMode.Raw, ComplexDataPart.Real); GetRandomComplexWaveformData(out waveform); // Set the X-Axis to display time wvfmGraph.XAxes[0].MajorDivisions.LabelFormat = timeFormatString; // Set the Y-Axis to display samples wvfmGraph.YAxes[0].MajorDivisions.LabelFormat = samplesFormatString; if (wvfmGraph.Plots[0].Mode != WaveformPlotMode.PlotComplexWaveform) wvfmGraph.ClearData(); wvfmGraph.PlotComplexWaveform<ComplexDouble>(waveform, options);
09-26-2012 09:23 AM
Jacob, thanks for the suggestion.
I found I could get what I wanted by turning off the X-Axis Major & Minor division lines...then creating my own custom divisions on the X-Axis where I need them to be.
This is working for now, but I'll try DisplayMode as Time becuase I'm curious if that will do it and be simpler.
Thanks again!