⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 plotdata.m

📁 Displays raw data of figure plots in separate spreadsheet tables
💻 M
📖 第 1 页 / 共 3 页
字号:
function [hDataFig, hSpreadsheet] = plotdata(varargin)
% plotdata Displays raw data of figure plots in a separate spreadsheet figure
%
% Syntax:
%    [hDataFig, hSpreadsheet] = plotdata
%    [hDataFig, hSpreadsheet] = plotdata(hPlotFig)
%    [hDataFig, hSpreadsheet] = plotdata(figureName, sheetName, xdata, ydata, xAxisName, yHeaders, ...)
%
% Description:
%    PLOTDATA(hPlotFig) scans the supplied figure handle for any plot axes;
%    for each plot axes found, a new spreadsheet is created with the plot
%    data values (X & Y, not Z). The data is displayed in the color of the
%    plot's original color. If the plot lines have a tag name or DisplayName
%    property (also used by legend), these are used as data column headers.
%    Note that all data vectors (xdata, ydata) must be the same length. 
%    If the plot or subplot(s) have titles, these are used as sheet names.
%    Data stats may be turned on/off using the checkbox at the bottom.
%    Data may be sorted, filtered, modified and exported to Excel -
%    explore the many options available in the top toolbar!
%    If the Excel plug-in is unavailable, tab-based Java tables are used.
%
%    PLOTDATA() is equivalent to PLOTDATA(gcf), scanning the currently
%    active figure.
%
%    PLOTDATA(figureName, sheetName,xdata,ydata,xAxisName,yHeaders, ...)
%    enables direct data display. Parameters #2-6 may be repeated: each set
%    (5 parameters each) will create a separate spreadsheet.
%
%    hDataFig = PLOTDATA(...) returns a handle to the data (spreadsheet)
%    figure
%
%    [hDataFig, hSpreadsheet] = PLOTDATA(...) also returns a handle to the
%    spreadsheet object - either an Excel ActiveX, or a Java tabbed-pane.
%
% Examples:
%    x=0:.01:10; ydata=[sin(x);cos(x)];
%    hFig=figure; plot([x;x]',ydata');
%    plotdata;  % scan the current figure for raw data (2 data lines)
%    plotdata(hFig);  % scan the selected figure handle
%    plotdata('title','sheet #1',1:3,magic(3),'X data',{'1','2','3'});
%
% Known issues/limitations:
%    1. Works best with Excel Web Component. This is available on any PC
%       that has Excel installed, or can be downloaded for free from
%       microsoft.com and used (read-only) even if Excel is not installed!
%    2. If the Excel plug-in is unavailable (e.g., on Linux), tab-based
%       Java tables are used but these provide more limited functionality.
%       When resizing java-based figure tables may become misplaced in their
%       container: resize again by a very small amount to snap into place.
%    3. Requires all plot lines in an axis to have the same xdata.
%       This limitation will be removed in a future version of PlotData.
%    4. Works on Matlab 7+. Might work on Matlab 6.5. Fails on Matlab 6.0
%
% Bugs and suggestions:
%    Please send to Yair Altman (altmany at gmail dot com)
%
% Change log:
%    2007-06-23: Added hSpreadsheet return arg; used Java tables if Excel is unavailable
%    2007-06-20: First version posted on <a href="http://www.mathworks.com/matlabcentral/fileexchange/loadAuthor.do?objectType=author&mfx=1&objectId=1096533#">MathWorks File Exchange</a>
%
% See also:
%    OfficeDoc (on <a href="http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=15192">MathWorks File Exchange</a>)

% Programmed by Yair M. Altman: altmany(at)gmail.com
% $Revision: 1.2 $  $Date: 2007/06/23 23:18:43 $

  try
      % Creates a new figure (or re-use existing one)
      hFig = findall(0,'tag','PlotDataFig');
      iconpath = [matlabroot, '/toolbox/matlab/icons/'];
      if isempty(hFig)
          % Prepare the figure
          hFig = figure('tag','PlotDataFig', 'menuBar','none', 'toolBar','none', 'Name','Plot data', 'NumberTitle','off', 'handleVisibility','off', 'IntegerHandle','off', 'filename','', 'ResizeFcn',@figResizeFcn);
          try
              % Set the Window icon
              jFig = get(hFig,'JavaFrame');
              figIcon = javax.swing.ImageIcon([iconpath 'profiler.gif']);
              jFig.setFigureIcon(figIcon);
          catch
              % never mind...
          end
      else
          clf(hFig);
          figure(hFig);   % bring to front
      end

      % Fix the ActiveX tags, position etc.
      acx = initSpreadsheet(hFig, varargin{:});

      % Return the data figure handle, if requested
      if nargout
          hDataFig = hFig;
          hSpreadsheet = acx;
      end
  catch
      v = version;
      if v(1)<='6'
          err.message = lasterr;  % no lasterror function...
      else
          err = lasterror;
      end
      try
          err.message = regexprep(err.message,'Error using ==> [^\n]+\n','');
      catch
          try
              % Another approach, used in Matlab 6 (where regexprep is unavailable)
              startIdx = findstr(err.message,'Error using ==> ');
              stopIdx = findstr(err.message,char(10));
              for idx = length(startIdx) : -1 : 1
                  idx2 = min(find(stopIdx > startIdx(idx)));  %#ok ML6
                  err.message(startIdx(idx):stopIdx(idx2)) = [];
              end
          catch
              % never mind...
          end
      end
      if isempty(findstr(mfilename,err.message))
          % Indicate error origin, if not already stated within the error message
          err.message = [mfilename ': ' err.message];
      end
      if v(1)<='6'
          while err.message(end)==char(10)
              err.message(end) = [];  % strip excessive Matlab 6 newlines
          end
          error(err.message);
      else
          rethrow(err);
      end
  end


%% Initialize the displayed spreadsheet object
function acx = initSpreadsheet(hFig, varargin)
      % Note: for help: http://msdn2.microsoft.com/en-us/library/microsoft.office.tools.excel.aspx
      % Requires: C:\PROGRA~1\COMMON~1\MICROS~1\WEBCOM~1\##\OWC##.DLL  (## = 9/10/11/...)
      % Note2: see http://techsupt.winbatch.com/ts/T000001033005F9.html for list of all XLS consts

      %set(hFig,'visible','on');   % for debugging...

      % Set figure name
      setFigureName(hFig, varargin{:});

      % Create (or reset) the spreadsheet object
      acx = createSpreadsheetObject(hFig);

      % If successfully created
      if ~isempty(acx)

          if ~isjava(acx)
              sheets = acx.Sheets;
          end

          % Set the data within the spreadsheet according to input type:
          if nargin<2 | isempty(varargin)  %#ok ML6   % No data - error
              %error('Must supply data to display in table!');
              varargin = {gcf};
          end
          if iscell(varargin) & ~isempty(varargin{1}) & ishandle(varargin{1}(1))  %#ok ML6  % figure handle
              hSrcFig = varargin{1}(1);

              % Place all axes in separate worksheets
              ax = sort(findall(hSrcFig,'type','axes','visible','on'));
              for axIdx = 1 : length(ax)
                  axTag = get(ax(axIdx),'tag');
                  if isempty(axTag) | isempty(strmatch(axTag,{'axLogo','legend'}))  %#ok ML6
                      % Set this axis's data in the current worksheet
                      setWorksheetAxisData(acx,ax(axIdx),axIdx);

                      if ~isjava(acx)
                          % Freeze pane beneath the headers (figure needs to be visible)
                          set(hFig, 'visible','on');
                          freezePane(acx,'C2');

                          % Add a new worksheet for the next data set
                          invoke(sheets,'Add');
                      end
                  end
              end
          else
              % Loop over all input args
              numArgs = length(varargin);
              sheetId = 1;
              setIdx = 1 + (numArgs>0 & ~isempty(varargin{1}) & (ischar(varargin{1}(1)) | isstruct(varargin{1}(1)) | ishandle(varargin{1}(1))));  %#ok ML6
              while setIdx <= numArgs
                  % Note: expected args format is: sheetName, xdata, ydata, xAxisName, yHeaders, ...
                  if ischar(varargin{setIdx})
                      sheetName = varargin{setIdx};
                      setIdx = setIdx + 1;
                  else
                      sheetName = sprintf('sheet%d',sheetId);
                  end

                  % data vals: {xdata, ydata}
                  data = varargin(setIdx:min(numArgs,setIdx+1));
                  setIdx = setIdx + length(data);

                  % headers: {xAxisName, yHeaders}
                  % Note: yHeaders may be a string or a cell array of strings
                  headers = varargin(setIdx:min(numArgs,setIdx+1));
                  %headers(~myCellfun(@ischar,headers)) = [];
                  if ~isempty(headers)
                      if ~ischar(headers{1})
                          headers = {};
                      elseif length(headers)>1 & ~ischar(headers{2}) & ~iscell(headers{2})  %#ok ML6
                          headers(2) = [];
                      end
                  end
                  setIdx = setIdx + length(headers);

                  % Set the data in the worksheet
                  setWorksheetData(acx, sheetName, data{:}, headers{:});

                  if ~isjava(acx)
                      % Freeze pane beneath the headers (figure needs to be visible)
                      set(hFig, 'visible','on');
                      freezePane(acx,'C2');

                      % Add a new worksheet for the next data set
                      invoke(sheets,'Add');
                  end
                  sheetId = sheetId + 1;
              end
          end

          % If any data was entered, then the last worksheet is empty and unused, so delete it
          if ~isjava(acx) & sheets.Count > 1  %#ok ML6
              invoke(acx.ActiveSheet,'Delete');
          end
      else
          % Do nothing - ActiveX not created so error msg was displayed
      end  % If ActiveX successfully created

%% Create spreadsheet object (or reset the existing one, if found)
function hActiveX = createSpreadsheetObject(hFig)
      % If this figure was already open with the ActiveX, do not recreate it
      %if ~isfield(handles,'hActiveX') | isempty(handles.hActiveX) | ~ishandle(handles.hActiveX)  %#ok ML6

          hActiveX = [];
          hFigPos = getPixelPos(hFig);

          % Try to select the latest possible ActiveX component
          version = 15;
          foundFlag = 0;
          while ~foundFlag & (version > 9)  %#ok ML6
              try
                  verStr = num2str(version);
                  actxNameStr = ['OWC' verStr '.Spreadsheet.' verStr];
                  hActiveX = actxcontrol(actxNameStr, [0,0,hFigPos(3:4)], hFig);  % hContainer 2nd output arg is invalid in ML6...
                  foundFlag = 1;
              catch
                  version = version - 1;
              end
          end

          % If not found, error
          if foundFlag

              % Set the control's position to be just inside the container's pixel position
              try
                  set(hFig, 'userdata',hActiveX);
              catch
                  set(hFig, 'userdata',hActiveX.Handle);  % old ML6 format
              end
              %set(hContainer, 'tag','acxSpreadsheetContainer', 'units','normalized', 'position',[0,0,1,1], 'userdata',hActiveX);  % forget ...'parent',hParent... - it creates a GUI overlap bacause of a Matlab bug...  % hContainer is unavailable in ML6...
              %uistack(findall(hFig,'tag','cbStats'),'top');   % doesn't work for an unknown reason
              cbStats = uicontrol('style','checkbox', 'parent',hFig, 'value',1, 'string','Stats', 'units','pixels', 'pos',[210,1,45,15], 'tag','cbStats', 'callback',@cbStats_Callback);  %#ok - cbStats unused
              pause(0.1);  %small delay to let the ActiveX time to render

              % Remove all default worksheets (the ActiveX requires at least one remain visible)
              sheets = hActiveX.Sheets;
              if sheets.Count < 1   % should never happen
                  invoke(sheets,'Add');
              else
                  while hActiveX.Sheets.Count > 1
                      invoke(hActiveX.ActiveSheet,'Delete');
                  end
              end

              % General properties
              hActiveX.DisplayDesignTimeUI = 1;

              % Clear the one visible worksheet
              range = selectRange(hActiveX,'$1:$99999');  %=hActiveX.Range('$1:$99999');
              invoke(range.EntireRow,'Select');
              invoke(hActiveX.Selection,'ClearContents');
              invoke(hActiveX.Selection,'ClearFormats');

          else  % Excel ActiveX plug-in not found

              % TODO: handle error if excel ActiveX not found (maybe use uitable?)
              %hMsg = uicontrol('style','text','string',{'Excel ActiveX','object not found'},'parent',hFig,'units','norm','position',[0,0,1,1],'FontSize',36,'Foreground','r','Background',get(hFig,'color'));
              %hhMsg = handle(hMsg);
              %%hhMsg.Position(4) = 0.5 + hhMsg.Extent(4)/2;  % construct invalid in ML6...
              %hhMsg.Position = [hhMsg.Position(1:3), 0.5 + hhMsg.Extent(4)/2];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -