16

Is there an option in matlab or a plugin/app or a trick such that if you are in an interactive command session, every time it would print out a matrix way too big for a human to look through, it redacts the output to either a warning of how big the matrix is or a summary (only a few rows and columns) of the matrix?

There are many times where I want to examine a matrix in the command window, but I didn't realize how big it was, so I accidentally printed the whole thing out. Or some place inside a function I did not code myself, someone missed a semicolon and I handed it a big matrix, and it dumps the whole thing in my command window.

It make sense that in 99.99% of the time, people do not intend to print a million row matrix in their interactive command window, right? It completely spams their scroll buffer and removes all useful information that you had on screen before.

So it makes much more sense for matlab to automatically assume that the user in interactive sessions want to output a summary of a big matrix, instead of dumping the whole thing into the command window. There should at least be such an option in the settings.

BW0
  • 757
  • 8
  • 14
  • You could always view the variable in the variable editor. I always use `open myVar`, but there are probably other ways. – David K Nov 06 '13 at 18:30
  • 3
    you can always use Ctrl+C to stop the matrix from showing... – bla Nov 06 '13 at 18:38
  • possible duplicate of [How to interrupt MATLAB IDE when it hangs on displaying very large array?](http://stackoverflow.com/questions/11779511/how-to-interrupt-matlab-ide-when-it-hangs-on-displaying-very-large-array) or at least in the same direction. I think you can try changing the `disp` function – Gunther Struyf Nov 06 '13 at 18:38

1 Answers1

21

One possibility is to overload the display function, which is called automatically when you enter an expression that is not terminated by ;. For example, if you put the following function in a folder called "@double" anywhere on your MATLAB path, the default display behavior will be overridden for double arrays (this is based on Mohsen Nosratinia's display.m for displaying matrix dimensions):

% @double/display.m
function display(v)
% DISPLAY Display a variable, limiting the number of elements shown.

name = inputname(1);    
if isempty(name)
    name = 'ans';
end

maxElementsShown = 500;
newlines = repmat('\n',1,~strcmp(get(0,'FormatSpacing'),'compact'));

if numel(v)>maxElementsShown,
    warning('display:varTooLong','Data not displayed because of length.');
    % OR show the first N=maxElementsShown elements
    % builtin('disp', v(1:maxElementsShown));
elseif numel(v)>0,
    fprintf([newlines '%s = \n' newlines], name);
    builtin('disp', v);
end

end

For example,

>> xx=1:10

xx = 

     1     2     3     4     5     6     7     8     9    10  

>> xx=1:1e4
Warning: Data not displayed because of length. 
> In double.display at 17 

EDIT: Updated to respect 'compact' and 'loose' output format preference.

EDIT 2: Prevent displaying an empty array. This makes whos and other commands avoid an unnecessary display.

Community
  • 1
  • 1
chappjc
  • 30,359
  • 6
  • 75
  • 132
  • Very nice, though I'd recommend it to also give a warning below your numbers if you just show the first elements. – Dennis Jaheruddin Nov 07 '13 at 14:15
  • Thanks for this script! An extra question: Is there a way detect whether a command is run under interactive mode or batch mode? This is so that in batch mode, disp function would be the default, and only during interactive mode would it be overloaded with the user custom one? – BW0 Nov 07 '13 at 18:26
  • 2
    One way you can detect if a command is run from a function (not just a script) or the command prompt (or basic script), is by checking the size of the stack. For example, `if numel(dbstack)>0, fprintf('You are in a function.\n'); else, fprintf('You are in the base workspace.\n'); end`. So, if you are in a function, you can set `disp = @(x) builtin('disp',x);` so that the function would use just the builtin `disp`. For `display`, modify display.m with `if numel(dbstack)>0, evalin('caller',['builtin(''display'',' name ');']); ...` so it detects a function is calling it and reverts to builtin. – chappjc Nov 07 '13 at 19:30
  • I'm using this, but I also like to point out that it doesn't reproduce the default behavior for empty matrices. –  Jul 30 '15 at 15:07
  • @moarningsun I recall there was some strange behavior with empty matrixes (without the `numel(v)>0` check). I don't remember what. Perhaps it would be OK to add `else fprintf([newlines '%s = \n' newlines ' []\n'], name);` to the `if` statement to get the default behavior. – chappjc Jul 30 '15 at 22:33
  • @chappjc Just curious, why do you put a comma at the end of your `if`/`elseif` lines? – askewchan Jun 24 '19 at 19:23