Search code examples
matlabmatrixidentify

How to highlight or identify a column with a specific value in matrix?


I would like to highlight or identify a column in a matrix with a specific value in MATLAB. Suppose I have a matrix A = [1 0 1 1 0 1; 1 1 0 0 0 1; 1 0 1 1 0 1; 0 1 1 0 0 1].

The result of the above matrix is a 5th column, as it contains all zeroes. I am also wondering if I could highlight the resulting column for identification. Please help me. I have a very large matrix to work on applying this principle.


Solution

  • Highlighting with red (stderr)

    Just for proof of concept, you could highlight some of your data in the command window, although I wouldn't suggest actually doing this. Consider the following code:

    A=randi(10,8);
    %ind = find(all(A==0,1),1) %for actual data
    ind = 5; %manual choice for demonstration
    
    for k=1:size(A,1)
        fprintf('%5d   ',A(k,1:ind-1));
        fprintf(2,'%5d   ',A(k,ind));
        fprintf('%5d   ',A(k,ind+1:end));
        fprintf('\n');
    end
    

    First we create a dummy matrix for demonstration purposes, and select column ind to highlight. Then we go along from line to line in A, we use fprintf(...) to write the non-highlighted values with a given format, then use fprintf(2,...) to write to stderr in red, then write the rest of the line, then newline. Note that for some reason fprintf(2,...) will not highlight the final character, I guess because usually this is \n and nobody noticed that highlighting is missing there.

    Also, you can play around with the formats inside fprintf to suit your needs. If you need to print floating points, something like '%10.8f' might work. Or '%g'. The main point is to have a fixed width+precision for your print in order to get pretty columns.

    For the sake of completeness, you can make it even a bit more messy to treat multiple highlightable columns:

    A=randi(10,8);
    %ind = find(all(A==0,1)) %for actual data
    ind=[5 2];
    
    fprintf('A = \n\n');
    for k1=1:size(A,1)
        for k2=1:size(A,2)
            if ismember(k2,ind)
                fprintf(2,'%5d   ',A(k1,k2));
            else
                fprintf('%5d   ',A(k1,k2));
            end
        end
        fprintf('\n');
    end
    fprintf('\n');
    

    I also added some extra printouts to make it prettier. Result: red highlight

    Highlighting with blue (links)

    As an afterthought, after some discussion with Luis Mendo, I decided that it's worth overdoing a bit while we're at it. You can turn your numbers into blue-and-underlined hyperlinks, making use of the built-in parsing of the <a href="URL">link</a> HTML tag implemented both in disp and in fprintf. Here's the corresponding code:

    A=randi(10,8);
    ind=[5 2];
    
    fieldlen=5; %width of output fields, i.e. 5 in '%5d'
    
    fprintf('A = \n\n');
    for k1=1:size(A,1)
        for k2=1:size(A,2)
            if ismember(k2,ind)
                fprintf([repmat(' ',1,fieldlen-length(num2str(A(k1,k2)))) '<a href="matlab:">%d</a>   '],A(k1,k2));
            else
                fprintf('%5d   ',A(k1,k2));
            end
        end
        fprintf('\n');
    end
    fprintf('\n');
    

    This will turn the elements of the highlighted column(s) into strings of the form '<a href="matlab:">3</a>' for an example value of 3.

    Another trick here is that hyperlinks starting with matlab: are parsed as proper matlab commands, which are activated when you click the link. You can try it by typing disp('<a href="matlab:help help">link</a>') in your command window. By setting <a href="matlab:">...</a> we make sure that nothing happens when someone clicks on the now-link-valued highlighted numbers.

    And on a technical note: we only want to include the actual number in the links (and not the preceding spaces), so we have to manually check the length of the string we are about to print (using length(num2str(A(k1,k2)))) and manually include the rest of the spaces before the number. This is done via the parameter fieldlen which I set at the beginning: this specifies the total width of each printing field, i.e. if we originally had fprintf('%5d',...) then we need to set fieldlen=5; for the same effect. Result: enter image description here