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

📄 plotdata.m

📁 Displays raw data of figure plots in separate spreadsheet tables
💻 M
📖 第 1 页 / 共 3 页
字号:

              % Create the tab pane
              tp = awtcreate('javax.swing.JTabbedPane');
              [jh,hContainer] = javacomponent(tp, [2,0,hFigPos(3:4)], hFig);  %#ok - jh is unused
              set(hContainer,'units','normalized', 'tag','jTabbedPane', 'userdata',tp, 'visible','on');
              set(hFig, 'userdata',tp);
              sp = schema.prop(handle(tp),'UserData','mxArray');  %#ok - sp is unused
              userdata = struct('container',hContainer, 'tables',handle([]), 'scroll',handle([])); 
              set(tp, 'userdata',userdata);
              hActiveX = tp;  % return tabbedPane to caller
              tp.setTabPlacement(tp.BOTTOM);

          end  % If found a relevant ActiveX
      %end  % if worksheet object does not yet exist

%% Set the data within the spreadsheet according to supplied axis
function setWorksheetAxisData(acx, ax, axIdx)
      % Set the worksheet name according to the axis title (remove all invalid chars)
      sheetName = regexprep(get(get(ax,'title'),'string'), '[\\{}]', '');
      if isempty(sheetName)
          sheetName = get(ancestor(ax,'figure'),'name');
      end
      if isempty(sheetName)
          %sheetName = 'Plot data';
          sheetName = ['Axis #' num2str(axIdx)];
      end

      % Loop over all axes plot lines
      % TODO: handle non-'type'='line' datum (annotations etc.)
      %hLines = findall(ax,'type','line');
      %hLines = sort(findall(ax,'-not','type','axes','-not','type','text'));
      hLines = sort(get(ax,'child'));
      numLines = length(hLines);
      if (numLines == 0)
          return;  % no data lines - skip this worksheet
      end
      validIdx = 1;
      for lineIdx = 1 : numLines
          hLine = hLines(lineIdx);
          newXData = get(hLine,'xdata')';
          if lineIdx>1 & ~isequal(size(newXData),size(xdata{1}))  %#ok ML6
              continue;  % All data vectors must be the same length
          end
          xdata{:,validIdx} = newXData;  %#ok mlint
          ydata{:,validIdx} = get(hLine,'ydata')';  %#ok mlint
          seriesName = strrep(get(hLine,'tag'),'\','');
          if isempty(seriesName) & isprop(hLine,'DisplayName')  %#ok ML6
              seriesName = strrep(get(hLine,'DisplayName'),'\','');
          end
          yHeaders{:,validIdx} = seriesName;  %#ok mlint
          if isprop(hLine,'color')
              color(validIdx) = getBGR(get(hLine,'color'));  %#ok
          else
              color(validIdx) = getBGR([0,0,0]);  %#ok mlint
          end
          validIdx = validIdx + 1;
      end

      % Get the X-axis name
      xAxisNames = get(get(ax,'XLabel'),{'string','userdata'});
      xAxisName = regexprep(strcat(xAxisNames{:}), '[\\{}]', '');

      % Set the data in the worksheet
      setWorksheetData(acx, sheetName, xdata, ydata, xAxisName, yHeaders, color);


%% Freeze pane beneath the headers
function freezePane(acx,cell)
      %acx.Range(cell).Select;
      selectRange(acx,cell);
      iter = 1;
      maxIter = 10;
      thisWin = acx.ActiveWindow;
      thisWin.FreezePanes = 1;
      while (iter < maxIter & ~thisWin.FreezePanes)  %#ok ML6
          pause(0.05);
          iter = iter + 1;
          thisWin.FreezePanes = 1;
      end

%% convert color from Matlab to Microsoft decimal BGR format (a number)
function bgrColor = getBGR(color)
      bgrColor = sum(floor(color*255) .* (256.^[0,1,2]));

%% convert color from Microsoft decimal BGR format to HTML hexa RGB format (a string)
function rgbColorStr = getRGB(color)
      bgrColorStr = dec2hex(color);
      rgbColorStr = bgrColorStr(:,[5,6,3,4,1,2]);

%% Get pixel position of an HG object (replacement for getpixelposition() in ML6)
function pos = getPixelPos(hObj)
    try
        % getpixelposition is unvectorized unfortunately! 
        pos = getpixelposition(hObj);
    catch
        % Matlab 6 did not have getpixelposition nor hgconvertunits so use the old way...
        pos = getPos(hObj,'pixels');
    end

%% Get position of an HG object in specified units
function pos = getPos(hObj,units)
    % Matlab 6 did not have hgconvertunits so use the old way...
    oldUnits = get(hObj,'units');
    if strcmpi(oldUnits,units)  % don't modify units unless we must!
        pos = get(hObj,'pos');
    else
        set(hObj,'units',units);
        pos = get(hObj,'pos');
        set(hObj,'units',oldUnits);
    end

%% Set worksheet data
function setWorksheetData(acx, titleStr, xdata, ydata, xAxisName, yHeaders, color)
      % Initialize
      if nargin<2,  titleStr = 'Plot data';  end
      if nargin<3,  xdata = [];  end
      if nargin<4,  ydata = [];  end
      if nargin<5 | isempty(xAxisName),  xAxisName = 'X data';  end  %#ok ML6

      % Args sanity check
      if ~ischar(titleStr)
          error('Args supplied to plotdata appear to be incorrect - please read help');
      end

      % Set the worksheet name
      sheetName = titleStr;
      retryIdx = 0;
      renameFlag = 1;
      panel = [];
      while renameFlag
          try
              if ~isjava(acx)
                  set(acx.ActiveSheet,'Name',sheetName);
              else
                  panel = javax.swing.JPanel;  % Double-buffered, Flow layout
                  acx.addTab(sheetName,panel);
              end
              renameFlag = 0;
          catch
              % will get here if the sheet name already exists, so we must rename it...
              retryIdx = retryIdx + 1;
              sheetName = [titleStr ' (' num2str(retryIdx) ')'];
              if retryIdx>10  % something large enough but still limited...
                  rethrow(lasterror);
              end
          end
      end
      if (retryIdx>0)
          %disp(['Sheet "' titleStr '" already exists - renaming "' sheetName '"']);
      end

      % Hide gridlines
      if ~isjava(acx)
          set(acx.ActiveWindow,'DisplayGridlines',0);
          set(get(acx.Cells,'Font'), 'Size',8);
      else
          % TODO
      end

      % Cell-ize
      if ~iscell(xdata) | isscalar(xdata{1}),  xdata = {xdata};  end  %#ok ML6
      if ~iscell(ydata) | isscalar(ydata{1}),  ydata = {ydata};  end  %#ok ML6
      if isempty(xdata) | isempty(xdata{1})  %#ok ML6
          %error(['No X data in "' titleStr '"']);
          xdata = cellstr(repmat(' ',length(ydata{1}),1));
      end

      % Set data column-wise
      if (size(xdata{1},1) < size(xdata{1},2)) & ~ischar(xdata{1}) & ~iscell(xdata{1}),  xdata = {xdata{1}'};  end  %#ok ML6
      if (size(ydata{1},1) < size(ydata{1},2)) & ~ischar(ydata{1}) & ~iscell(ydata{1}),  ydata = {ydata{:}'};  end  %#ok ML6
      numLines = length(ydata) * size(ydata{1},2);
      if (numel(ydata) == 1)
          newData = {};
          for colIdx = 1 : numLines
              newData{colIdx} = ydata{1}(:,colIdx);  %#ok mlint
          end
          ydata = newData;
      end

      % Default headers = 'Field #...'
      if nargin<6,  yHeaders = {};  end
      if ~iscell(yHeaders),  yHeaders = {yHeaders};  end
      for fieldIdx = 1 : numLines
          if fieldIdx > length(yHeaders) | isempty(yHeaders{fieldIdx})  %#ok ML6
              yHeaders{fieldIdx} = ['Field #' num2str(fieldIdx)];
          end
      end

      % Simple processing for Java table...
      if isjava(acx)
          % Prepare the data table
          columnNames = [xAxisName, yHeaders];
          userdata = get(acx, 'userdata');
          hContainer = userdata.container;
          ppos = getPixelPos(hContainer);
          tpos = ppos(3:4); %-[4,15];
          colWidth = (tpos(1)-55) / length(columnNames);
          [ett table] = prepareJTable(columnNames,colWidth,hContainer, [xdata(:,1),ydata]);

          % Enable multiple row selection, auto-column resize, and auto-scrollbars
          table.setName(sheetName);
          table.setPreferredScrollableViewportSize(java.awt.Dimension(tpos(1)-20,16))
          table.setSelectionMode(javax.swing.ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
          %table.setAutoResizeMode(table.AUTO_RESIZE_SUBSEQUENT_COLUMNS)
          sp = com.mathworks.widgets.spreadsheet.SpreadsheetScrollPane(table);
          tableSize = java.awt.Dimension(tpos(1)-5,tpos(2)-35);
          sp.setPreferredSize(tableSize);
          sp.setVerticalScrollBarPolicy(sp.VERTICAL_SCROLLBAR_AS_NEEDED);      %_ALWAYS
          sp.setHorizontalScrollBarPolicy(sp.HORIZONTAL_SCROLLBAR_AS_NEEDED);  %_ALWAYS
          %sp.setRowHeader([]);  % removes problematic row headers (at left of table)

          % Loop over all data fields and set the column colors
          if nargin > 6
              columns = table.getColumnModel;
              color = getRGB(color);
              columns.getColumn(0).setHeaderValue(['<html><b>' xAxisName '</b></html>']);
              for fieldIdx = 1 : length(yHeaders)
                  columns.getColumn(fieldIdx).setHeaderValue(['<html><b><font color="#' color(fieldIdx,:) '">' yHeaders{fieldIdx} '</font></b></html>']);
              end
          end

          % Add the table to the tab pane
          panel.add(sp);

          % Store table & ScrollPane for use in resizing
          userdata.tables(end+1) = handle(table);
          userdata.scroll(end+1) = handle(sp);
          set(acx, 'userdata',userdata);

          % Set the focus, to force an immediate repaint
          acx.requestFocus;
          drawnow;
          return;
      end

      % Default color = Black
      if nargin<7
          color(1:numLines) = getBGR([0,0,0]);  % [0,0,0] = Black
      end

      %[R,C] = size(data);
      C = numLines + 1;
      if ischar(xdata{1,1})
          R = size(xdata,1);
      else
          R = length(xdata{1});
      end

      % Set headers into the spreadsheet
      % TODO: handle case of non-aligned x-data (i.e., xdata(:,1)~=xdata(:,2))
      %acx.Range(['B1:' nn2an(1,C+1)]).Select;
      selection = selectRange(acx,['B1:' nn2an(1,C+1)]);
      selection.Value = [xAxisName yHeaders];
      set(selection.Font,'Bold',1);
      set(selection.Font,'Color',hex2dec('0000FF'));  % Red
      set(invoke(selection.Border,'Item',4), 'Weight',3);
      selection.HorizontalAlignment = -4108;  % =xlCenter

      % Insert the stats section
      statNames = {'min';'max';'average';'median';'stdev';'counta'};
      numStats = length(statNames);
      setWorksheetStats(acx, C, statNames);

      % Set the actual data
      % TODO: handle case of non-aligned x-data (i.e., xdata(:,1)~=xdata(:,2))
      %data = mat2cell(data, repmat(1,1,R), repmat(1,1,C));
      %acx.Range(['B' num2str(2+numStats) ':' nn2an(R+numStats,C+1)]).Value = data;
      
      % X column data:
      if ~ischar(xdata{1,1}) & ~iscell(xdata{1,1})  %#ok ML6
          xdata = mat2cell(xdata{1}(:,1), repmat(1,1,R), 1);
      end
      %acx.Range([nn2an(2+numStats,2) ':' nn2an(R+1+numStats,2)]).Value = xdata;
      range = selectRange(acx,[nn2an(2+numStats,2) ':' nn2an(R+1+numStats,2)]);
      range.Value = xdata;

      % Y column(s) data:
      if (numLines > 0)
          if (size(ydata{1},1) == R)
              for lineIdx = 1 : numLines
                  % Enter the data
                  data = ydata{:,lineIdx};
                  if ~iscell(data)
                      data = mat2cell(data, repmat(1,1,R), 1);
                  end

                  % Empty & NaN cells are NOT accepted by XLS ActiveX => 1x0 single...
                  [data{cellfun('isempty', data)}] = deal(single(zeros(1,0)));
                  %nanIdx = cellfun(@(x)(~isempty(x) & isnumeric(x) & isnan(x)), data);  %#ok ML6 - annonymous funcs invalid in ML6
                  nanIdx = [];
                  for cellIdx = length(data) : -1 : 1
                      x = data{cellIdx};
                      nanIdx(cellIdx) = ~isempty(x) & isnumeric(x) & isnan(x);  %#ok mlint
                  end

⌨️ 快捷键说明

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