image thumbnail

Simple Plot, Zoom and FFT GUI

by

 

03 Dec 2007 (Updated )

GUI to select a Simulink output file or workspace variable, m-file outputs or oscilloscope data. Zo

plotFFT_v02
function  plotFFT_v02
%=====================================================================
%   Frequency FFT Plot - Used GUIDE for GUI
%=====================================================================
%   Called from plotZoom_vxx.m. Type help GetData_v9 for more informaion
% 
%   Uses nested functions
%     J. Fallon                   Staff Engineer  12-04-07 GE Aerospace
%     937-237-8215            silverrock@ ameritech.net
%     937-898-5881 x325   WORK # - Presently out on disability
%
%  WINDOW  function is found to be not very useful in this application.
%   Left it in anyway. Same with down sample.
%=====================================================================
      set(0,'ShowHiddenHandles','on');
      hFigSpec = open('plotFFTGUI_v02.fig');           % figure developed using 
      set(hFigSpec,'units','pixels');                            %... GUIDE                                 set(hFigSpec,'units','pixels');    set(hFigSpec,'units','characters');             
%       set(hFigSpec,'Position',get(hFigSpec,'Position') - [50 100 0 0]);
      cfig = get(gcf,'color');

      hAxes = findobj(hFigSpec,'Tag','axesFreq');    % Find axes named by GUIDE 
                                                                                       %... and rename
      % Define callbacks for buttons
      % Find the button named by GUIDE and rename
      hXaxisButton = findobj(hFigSpec,'Tag','Xaxis_toggle');  
      % define Xaxis button handler  
      set(hXaxisButton,'Callback',@XaxisCallback);  
      
      screenSize = get(0,'MonitorPosition');    % get screen size
      % scale for new resolution different from designed 1280 x 800 screen
      % example: original designed lower right point = 451 pixels
      %                   point scale = (451 / 1200) x present screen width  
      %                                       = 0.3523 x present screen width
      positionX = 0.4063* screenSize(1,3);  positionY = 0.3212 * screenSize(1,4);
      positionW = 0.575 * screenSize(1,3); positionH = 0.57 * screenSize(1,4);
      % set new figure position
      set(hFigSpec,'Position',[positionX  positionY   positionW  positionH] );       
  
     % Find the button named by GUIDE and rename 
      hTypeButton = findobj(hFigSpec,'Tag','Type_toggle');                           
      set(hTypeButton,'Callback',@TypeCallback);         % define plot type button
      axisType = findobj(hFigSpec,'Tag','axisTitle');       %...  handler  
      dB_title = findobj(hFigSpec,'Tag','dbTitle');    

        % Find the buttons, etc. named by GUIDE and rename 
      hExitButton = findobj(hFigSpec,'Tag','exitBut');                                      
      set(hExitButton,'Callback',@ExitCallback);                  % name callback routine

      hNewButton = findobj(hFigSpec,'Tag','newButton'); % new data button
      set(hNewButton,'Callback',@NewCallback);               % define 'New data' 
                                                                                                 %...button handler  
      hDnSample = findobj(hFigSpec,'Tag','downSample');  % down sample select             
      set(hDnSample,'Callback',@dnSampleCallback);           % define handler  

      hWindow = findobj(hFigSpec,'Tag','selectWindow');  % window selection         
      set(hWindow,'Callback',@WindowCallback);                % define handler  

      hFigSmall = open('small_plot_03.fig');                 % smaller figures 
      set(hFigSmall,'units','pixels');                               % ... developed using GUIDE

      set(hFigSmall,'Position',get(hFigSmall,'Position') - ...
                              [500  0  0  0], 'Menubar','none','Toolbar','none');
                        
      screenSize = get(0,'MonitorPosition');    % get screen size
      % scale for new resolution different from designed 1280 x 800 screen
      % example: original designed lower right point = 451 pixels
      %                   point scale = (451 / 1200) x present screen width  
      %                                       = 0.3523 x present screen width
      positionX = 0.0156* screenSize(1,3);  positionY = 0.3438 * screenSize(1,4);
      positionW = 0.2977 * screenSize(1,3); positionH = 0.5475 * screenSize(1,4);
      % set new figure position
      set(hFigSmall,'Position',[positionX  positionY   positionW  positionH] );       
                         
                              
                              

      hSmallAxes = findobj(hFigSmall,'Tag','smallAxes');   % Find axes named for  
                                                                                  % ...smaller plots and 
                                                                                  %... rename....first is time
      hSmallFreq = findobj(hFigSmall,'Tag','smallFreq'); %  second is frequency dB  
      hSmallAng = findobj(hFigSmall,'Tag','angAxes');    % ... then angle      
      hDoneButton = findobj(hFigSmall,'Tag','doneButton');    
     % small plot GUI done button      
      set(hDoneButton,'Callback',@DoneCallback);          % define handler   

      % small plot GUI refresh button 
      hRefreshButton = findobj(hFigSmall,'Tag','refreshButton');           
      set(hRefreshButton,'Callback',@RefreshCallback);   % handler
 
      % Get data from WS
      WSvariables = evalin('base','who');  
      % Get all workspace variables (string names)
      WSindex = strmatch('GUI_data', WSvariables,'exact'); 
      % point to list of WS data (time voltage and sample frequency
      all_in = evalin('base',WSvariables{WSindex});                      

      WSvoltage = all_in.volt;                              % get voltage vector
      sizeVector = size(WSvoltage);
      if sizeVector(2) > 1
            WSvoltage = WSvoltage';                    %  if row vector -> change to column
      end
      sampleFreq_In = all_in.fs;                          % get sample frequency
      WStime = (0:1:length(WSvoltage)-1)*(1 / sampleFreq_In);   
 
      GainNot_dB = true;                                     % start with gain not dB
      xAxesLinear = false;                                   % start with linrear frequency axes                                                                   

      windowFlag = false;                                    % default to no window
      windowType = 1;                                         % .. with no type  
      downSampleFlag = false;                          % default is none
      downSampleValue = 1;                               % ...  

      useData = {windowFlag   windowType...
                  downSampleFlag   downSampleValue};  % assign data to cell
      set(hFigSpec,'UserData',useData);                      % temporary save

      % plot 
      [FFTfrequency  FFTgain  FFTangle] = FFT_setup;  % run  FFT            
      smallPlots(WStime,  WSvoltage,   FFTangle);      % plot GUI with 3 small axes
      freq_plot(FFTfrequency, FFTgain);                        % Initial plot is spectrum              

    %===================================================================
    % frequency plot routine - called after FFT_setup
    %=================================================================== 
   function freq_plot(inFrequency, inGain)
        axes(hAxes)                                                       % bring up  large fft axes
        inGain = 2 * inGain;                                           % double the gain>
         
        if GainNot_dB == true  
              minX = floor(min(inFrequency) / 10);     
              gainLabel = 'Gain - Linear';      % change to linear gain label (above plot)
              stem(inFrequency,inGain,'Marker','none',...
                                    'LineWidth',2,'Color','k');    % plot the stem graph
       else                                                      %      else: udB gain 
              gainLabel = 'Gain [dBu]';          %  change to udB gain label (above plot)
              minX = 0;    
              inGain = 20*log10(inGain*10^6);      %  change gain to udB
              % use regular plot -  stem doesn't show up well  with udB gain 
              h = plot(inFrequency,inGain, 'Color','k', 'LineWidth',1,...                         
                                                                           'Marker','none');                         
        end
        if xAxesLinear == false                         % for case where not udB                                         
              axesXscale = 'log';                      % log
        else                                                         %  ... else
              axesXscale = 'linear';                  % linear axes     
        end
     % go approximately one decade down from lowest freq    
                                                                    
     del = abs(max(inGain) - min(inGain)) * 0.08;         % scale top and bottom limits
%      minX = floor(min(inFrequency) / 10);     
     set(hAxes,'YLim',[min(inGain)-del    max(inGain)+del],...  % apply scaling and 
                 'XLim',[minX   max(inFrequency)], 'Xscale', axesXscale,... %turn on grid              
                'XGrid', 'on', 'YGrid', 'on');
     % Create labels
     ylabel(gainLabel, 'FontSize',10, 'FontWeight','bold');        %label x and y axis                                         
     xlabel('Frequency (Hz)', 'FontSize', 10,  'FontWeight','bold');
   end

    %===================================================================
    % log-linear Xaxis type button pressed
    %===================================================================
    function XaxisCallback(hObject, eventdata)
    % Callback function when the button is pressed
        if xAxesLinear == false                               % if X axis is log
                  xAxesLinear = true;                          %  set flag for linear  
                  set(hXaxisButton,'String','Log');  % change the button label to log 
        else                                                               %... for next  selection
                  xAxesLinear = false;                         % set flag for log                    
                  set(hXaxisButton,'String','Linear'); % change the button label to linear
        end
        [FFTfrequency  FFTgain  FFTangle] = FFT_setup;      % setup and replot FFT
        freq_plot(FFTfrequency, FFTgain)                                                
    end

    %===================================================================
    % Down Sample selection made
    %===================================================================
    function dnSampleCallback(hObject, eventdata)
         list_entries = get(hDnSample, 'String');
         index_selected = get(hDnSample, 'Value');           % get the down sample 
         selected_item = list_entries{index_selected(1)};   % ... selection #  
         useData = get(hFigSpec,'UserData');                     % get the saved user data
         if length(selected_item) <  3                                    %  if not 'NONE selection
             useData(3) =  num2cell(true);                              %  flag as a down sample
             useData(4) =  num2cell(str2num(selected_item));  % return with the # 
         else                                                                                    %... selected
             useData(3) =  num2cell(false);                                   % handles 'NONE' selection    
             useData(4) =  num2cell(0);
         end
         set(hFigSpec,'UserData',useData);                             % save user data   
         [FFTfrequency  FFTgain  FFTangle] = FFT_setup;    % setup and replot FFT 
         freq_plot(FFTfrequency, FFTgain) ;  
    end
 
    %===================================================================
    % Window selection made
    %===================================================================
    function WindowCallback(hObject, eventdata)
        list_entries = get(hWindow,'String');                % get the window selection #  
        index_selected = get(hWindow,'Value');           % ...and value
       selected_item = list_entries{index_selected(1)};
       useData = get(hFigSpec,'UserData');
       if index_selected ~=  1                                          % if 'NONE'
           useData(1) =  num2cell(true);                          % set the return flag true
           useData(2) =  num2cell(index_selected);
       else
           useData(1) =  num2cell(false);                       % set the return flag false
           useData(2) =  num2cell(0);                             %  return '0' for 'NONE'
       end
       set(hFigSpec,'UserData',useData);                          % save user data      
       [FFTfrequency  FFTgain  FFTangle] = FFT_setup;  % setup and replot FFT  
       freq_plot(FFTfrequency, FFTgain) ;   
   end

    %===================================================================
    % Type Button
    %===================================================================
    function TypeCallback(hObject, eventdata)
    % Callback function when the dB button is pressed
         if GainNot_dB == true                            % if not dB now
            GainNot_dB = false;                            % ...make dB
            set(hTypeButton,'String', 'Linear');  % switch the button label to 'Linear'
            set(dB_title,'String', 'Gain dBu');      % change label on right upper corner
         else                                                           % else if dB change to linear                                                                                       
            GainNot_dB = true;                             % set the flag
            set(hTypeButton,'String', 'dBu');     % switch the button label to 'dB'
             set(dB_title,'String', 'Gain LINEAR');% change label on right upper corner 
         end
            [FFTfrequency  FFTgain  FFTangle] = FFT_setup; % setup and replot FFT   
            freq_plot(FFTfrequency, FFTgain);            
    end

    %===================================================================
    % New Button - back to selection of file or WS variable
    %===================================================================
    function NewCallback(hObject, eventdata)
    % Callback function when the EXIT button is pressed
        close all;                                                            % clean up  
        GetData_v13;                                                     % go back to beginning
    end

    %===================================================================
    % Exit Button
    %===================================================================
    function ExitCallback(hObject, eventdata)
    % Callback function when the EXIT button is pressed
        close(hFigSpec);                               % close main figure
      try
        close(hFigSmall);                               % try to close small GUI ( with 3 figures)
      catch                                                       % ... trap if already closed by it's own 
      end                                                          % .. 'DONE' button  
    end

   %===================================================================
    % done Button on small axes figure
    %===================================================================
    function DoneCallback(hObject, eventdata)
    % Callback function when the DONE button is pressed
        close(hFigSmall);                                  % close small GUI ( with 3 figures)                                                        
    end                                                               % ... with it's own 'DONE' button

   %===================================================================
    % Refresh Button for small axes figure
    %===================================================================
    function RefreshCallback(hObject, eventdata)
    % Callback function when the DONE button is pressed
           hSave = get(hFigSmall,'UserData');                              % get user data info
           timeVector =cell2mat(hSave(1));                                   %.. time vector,                                                       
           voltageVector =cell2mat(hSave(2));                             % ...voltage vector
           angleVector =cell2mat(hSave(3));                                 % ...and angle vector
           smallPlots(timeVector, voltageVector, angleVector)   %  re-do the plots
       end

    %===================================================================
    % Setup FFT data 
    %===================================================================
    function [FFTfrequency  FFTgain  theta] = FFT_setup(hObject, eventdata)
        FFTgain = [];  FFTfrequency = [];   theta = [];    % initialize variables
         
        Vdata = WSvoltage;
        Tdata = WStime;
        sampleFrequency = sampleFreq_In;                %  get the input sample freq
        hUserData = get(hFigSpec,'UserData');           %  get the saved data
 
        windowFlag = cell2mat(hUserData(1));             % get window flag
        windowType = cell2mat(hUserData(2));             % ...type
        downSampleFlag = cell2mat(hUserData(3));    % get down sample flag
        downSampleValue = cell2mat(hUserData(4));   % amount of down sample
         
        if downSampleFlag == true                                  % if down sample selected   
                [Vdata  sampleFrequency Tdata] =...
                                  DownSampleHandler(Vdata);    % calculate down sample info
        end
        if windowFlag == true                             % if a window is selecte
                WinData = WindowHandler;          % get the window
                Vdata = Vdata.*WinData;               % apply window to data
        end                                                           % Update small axes to show the .... 
       TimePlot(Tdata, Vdata);                          % ... effect of window if selected                                                                                
        N = length( Vdata);                                % # of data points 
        dt = 1/ sampleFrequency;                     % sample time
        f0 = 1/ (N * dt);                                        %  freq. resolution in Hz
        Go = (1/N) * fft(Vdata);                           % units are tbd 
        % for plotting purposes, throw away dc, nyquest
        %...& neg. freqs (i.e. > N/2)
        for i = 1:(N/2 - 1)
              FFTgain(i) = 2*abs(Go(i+1)); 
              FFTfrequency(i) = i * f0;
              theta(i) = atan2(imag(Go(i)),real(Go(i))) * (180/pi); 
       end
            %===============================================================
            % apply down sample - user selects in GUI dropdown
            %================== ============================================
            function [voltageOut  newSampleFrequency  timeOut] = ...
                                        DownSampleHandler(voltageData); 
                 % calculate new down sampled voltage vector     
                 voltageOut = decimate(voltageData , downSampleValue);                                 
                 newSampleFrequency = round(sampleFrequency...
                                                     / downSampleValue);        % ...
                 deltaTime = 1 / newSampleFrequency;               % new sample tinee
                 timeOut = (1:length(voltageOut)) * deltaTime;  % calculate new time 
            end                                                                               % ...vector
            %=============================================================== 
            % apply window - selected by GUI dropdown
            %=============================================================== 
            function[window_out] = WindowHandler
             lengthWindow = length(Vdata);                         % make the window same
             switch windowType                                              % .... length as the data
                 case 2                                                                 % position #1 is 'NONE'
                     window_out = hamming(lengthWindow); % Hamming           
                 case 3
                     window_out = hann(lengthWindow);                % Hann
                 case 4
                     window_out = kaiser(lengthWindow);               % Kaiser
                 case 5
                     window_out = blackman(lengthWindow);         % blackman
                 case 6
                     window_out = rectwin(lengthWindow);             % Rectangle
                 otherwise
             end
            end
    end

    %===================================================================
    % small plots time-FFT-angle - On separate Figure
    %=================================================================== 
    function smallPlots(in_Time, in_Voltage, FFTangle)
        axes(hSmallAxes)                                         % select axes for time-volt plot
        hSave = {in_Time  in_Voltage  FFTangle}; % save inputs in 'UserData' of the
        set(hFigSmall,'UserData',hSave);               % ....  axes used in 'REFRESH' 
%                                                                             % ... button handler     
        TimePlot(in_Time, in_Voltage)                    % call function to plot the data    
        N = length(in_Voltage);                               % # of data points 
        dt = (in_Time(2) - in_Time(1));                     % calculate sample time
        freqOut = 1/ (N * dt);                                     % freq. resolution in Hz
        gainFFT = (1/N)*fft(in_Voltage);                 % use fft function on input data       
        % for plotting purposes, throw away dc, nyquest
        %...& neg. freqs (i.e. > N/2)
        for i = 1:(N/2 - 1)                                                                     
               FFTgain(i) = abs(gainFFT(i+1));      %  make real
               FFTfrequency(i) = i * freqOut;         % calculate actual frequency values
               % calculate angle in degrees
                theta(i) = atan2(imag(gainFFT(i)),real(gainFFT(i))) * (180/pi);               
        end
%   try
        Gm = 20*log(FFTgain*10^6);                       %   gain is in u_dB                                                                                                                                            
%   catch                                                                %  handles some errors?
%  end
        axes(hSmallFreq)                                        % select axes for gain-freq plot   
        % make the graph
        plotFFT = plot(FFTfrequency, Gm, 'Color','k', 'LineWidth',1, 'Marker','none'); 
        set(gca,'XScale','log');                                                % change X axis to log                                                
        YaxisLimitDelta = abs(max(Gm) - min(Gm)) * 0.08;  % calculate  the size for                       
        ylabel('Amplitude - dBu', 'FontSize',8,...                  % ... + / - to Y axis   
                                    'FontWeight','bold');                      % annotate
        xlabel('FFT - Frequency (Hz)', 'FontSize', 8,  'FontWeight','bold');
        set(hSmallFreq,'YLim',[min(Gm)-YaxisLimitDelta...
                        max(Gm)+YaxisLimitDelta],...   % apply limits and grid ON
                       'XLim',[0  max(FFTfrequency)], 'XGrid', 'on', 'YGrid', 'on'); 
        
        axes(hSmallAng)                                            % select axes for angle-freq plots           
       plotAngle = plot(FFTfrequency, theta,...
       'Color','k', 'LineWidth',1, 'Marker','none');   % make the graph
       set(gca,'XScale','log');                                    % axis to log
      % calculate  the size for + / - to Y axis     
       YaxisLimitDelta = abs(max(FFTangle) - min(FFTangle)) * 0.08;                                         
       ylabel('Phase - degrees', 'FontSize',8, 'FontWeight','bold');  % annotate
       xlabel('FFT - Frequency (Hz)', 'FontSize', 8,  'FontWeight','bold');
       set(hSmallAng,'YLim',[min(FFTangle)-YaxisLimitDelta ...
                             max(FFTangle)+YaxisLimitDelta],...    % apply limits and grid ON 
                             'XLim',[min(FFTfrequency)  max(FFTfrequency)],...
                             'XGrid', 'on', 'YGrid', 'on'); 
    end
   %===================================================================
    % Plot Time only
    %===================================================================
    function TimePlot(time_in, volt_in)
         axes(hSmallAxes)           % select axes for time-volt plot (alraedy selected?)
%        
        time_in = time_in* 1000;  % adjust for msec plot units
       % make the graph 
        hPlot = plot(time_in, volt_in, 'Color','r', 'LineWidth',2, 'Marker','none');  
        zoom on; grid;                                                     % grid and zoom ON
        del = abs(max(volt_in) - min(volt_in)) * 0.08;  % calculate  the size for + / - 
  try                                                                               %... to Y axis     
        %  make the graph
        set(hSmallAxes,'YLim',[min(volt_in)-del    max(volt_in)+del],...  
                   'XLim',[min(time_in)  max(time_in)], 'XGrid', 'on', 'YGrid', 'on');
 catch
 end
        % Create labels
        ylabel('Amplitude', 'FontSize',8, 'FontWeight','bold');        % more annotation
        xlabel('Time (msec)', 'FontSize', 8,  'FontWeight','bold');
    end
end                                                                                                     % END PROGRAM
 
 
 

Contact us