2

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.

Stewie Griffin
  • 14,889
  • 11
  • 39
  • 70
Azhar
  • 23
  • 3

3 Answers3

4

How about combining find and all to get the column index of the all-zero column like this?

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];
 
ind = find(all(A==0,1))
ind = 
    5

The second input argument to all is to specify that it's along the first dimension, i.e. rows. It's not really necessary here, but I find that it's a good practice as you're always sure it's the right dimension. This is especially important if there are scenarios where you might get a 1xn vector instead of mxn.

Create a colored matrix:

This is a hack, and I don't necessarily recommend it, but if you really want to do this in MATLAB, this is an alternative. Also, I think you might learn quite a lot about MATLAB when doing this, so it might be worth the time.

You can create a colored plot with all values 1 except those in column 5 that will be 0 (or the other way around, doesn't matter) using imagesc. This will give a plot with only two colors, one for those values that are 1, and one for those that are 0. You can select which colors you want with colormap. Then you create a mesh to determine the location of all the values you want to show, convert the matrix to strings using num2str, and combine it all. You need to experiment some to get the correct locations, as you probably want less padding between the rows than the columns. You can use this answer as a guide. In the end, remove the axes. It should be fairly simple to adapt if you read and try to understand each line of the referenced answer.

The simple approach:

I have a very large matrix...". Such matrices are often not a good idea to include in a report. However, if you really want to, I actually suggest you copy paste it from the variable explorer and into MS Excel (or use xlswrite if you're doing this more than once). Since you know which column you want to color, it should be fairly simple to click the "color button".

Community
  • 1
  • 1
Stewie Griffin
  • 14,889
  • 11
  • 39
  • 70
  • Wow. Such a quick response. Thanks a lot Stewie. This is exactly what I wanted. And by highlighting, I mean to add color for easy identification. – Azhar Sep 23 '15 at 07:36
4

The following displays the matrix in the command window with the matching columns in boldface. There may be several matching columns, and arbitrary column values can be matched.

A = [1 0 1 0 0 1; 1 1 0 1 0 1; 1 0 1 0 0 1; 0 1 1 1 0 1]; %// matrix
c = [0;1;0;1]; %// column to be matched
nn = find(all(bsxfun(@eq, A, c),1)); %// indices of matching columns
s = cellstr(num2str(A)); %// cell array of strings, one for each row; all same length
for n = nn %// for each matching column, with index n
    s = regexprep(s, '\S+', '<strong>$0</strong>', n); %// make bold n-th value of each cell
end
s = vertcat(s{:}); %// convert back into a char array; all strings have the same length
disp(s); %// display

The result in this example is

enter image description here

Luis Mendo
  • 110,752
  • 13
  • 76
  • 147
2

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

Community
  • 1
  • 1