Loren on the Art of MATLAB

Indexing Terminology 11

Posted by Loren Shure,

Someone recently asked me to discuss X-Y versus row-column indexing.

Contents

Two Conventions

When calling functions in MATLAB that create or reference arrays, there are two different conventions for specifying the first two dimensions of an array:

  • matrix indexing, i.e., rows and columns
  • Cartesian , i.e., X and Y

These different conventions get used depending on whether the array is strictly an array or when it has a probable physical interpretation in terms of Cartesian grid.

Matrix versus Cartesian Frameworks

In MATLAB, we index into matrices using row and column indices. That is, for matrix

A = magic(3)
A =
     8     1     6
     3     5     7
     4     9     2

I can reference the last element in the second row like this:

A(2,3)
ans =
     7

or

A(2,end)
ans =
     7

and to retrieve the first element of columns 1 and 3, I type this:

A(1,[1 3])
ans =
     8     6

Check out this post to get a fairly complete picture of indexing in MATLAB.

Plotting Matrices

The options xy and ij for axis allow us to control whether to view the data just the way the matrix is displayed (the (1,1) element is in the upper left corner):

colormap(jet(9))
image(A)
colorbar

or we can view the image/matrix as a top-down view of a physical "map" with the y-values now increasing along the vertical axis.

axis xy

In images, the matrices column values plot vertically. In line plots, the columns are plotted vs. their indices, making columns plot horizontally.

h = plot(A);
legend(h,{'Column 1','Column 2','Column 3'})

Creating an N-Dimensional Grid

ndgrid uses matrix indexing since it is designed to suit working in any number of array dimensions.

[ii, jj] = ndgrid(1:3,1:2)
ii =
     1     1
     2     2
     3     3
jj =
     1     2
     1     2
     1     2

Creating an 2- or 3-Dimensional Grid

On the other hand, mesh, interprets its first inputs in a Cartesian framework since it is used primarily for working with 2- and 3-dimensional plots, often depicting something over an area or volume.

[xx, yy] = meshgrid(1:3,1:2)
xx =
     1     2     3
     1     2     3
yy =
     1     1     1
     2     2     2

In the Remarks section of the documentation for meshgrid, you will find a discussion of this, especially with respect to inverting the first two input arguments compared to ndgrid. There is related discussion in the Description section for the function mesh.

Functions designed for two or three dimension, such as contour and quiver, usually work in Cartesian coordinates. Functions that are designed to work in N-dimensions generally work with a matrix indexing framework. Be sure to check the help for functions you use to see which convention applies.

Thoughts?

Any ideas on what we can do, perhaps in examples or documentation (or eslewhere?) to help people out with this potential confusion? If so, please post here.


Get the MATLAB code

Published with MATLAB® 7.4

11 CommentsOldest to Newest

I encountered this ambiguity just this week using contourf(). My contours kept coming out just the opposite as what I expected. It wasn’t until I tried plotting a non-square matrix before I realized something was wrong.

My suggestion to MATLAB is to pick a convention and stick with it.

Jessee-

Which convention to choose? And why that one? Both are natural in different situations. Hence the dilemma.

–Loren

I personally usually think of “meshgrid” as the worst Matlab function – note that I do enjoy most of them.

I have my own imho-owell-oriented meshgrid function, with a different name, but some functions such as interp2 (TBC) require the grid to be meshgrid-generated !

This change of convention is a nightmare. As an image processing engineer, I find it so easier to keep the same convention : x goes with row index, hence row index is a natural discretization of x direction, while y goes with column index.

Obviously the obtained Cartesian grid is not in the usual direction (north to south for X and west to east for Y), but it makes a lot of computation so easier – especially when going from continuous to discrete representations, which is when hard things usually begin (think of a warping between two images, for instance).

I think it is easier to rotate the Cartesian coordinate system, in order to have a consistent (i,j) and (x,y) notation. It keeps both the axes direct (angles in the right directions) and the matrix multiplication (IDL convention is a nightmare).

Anyhow, this is my Humble Opinion – Keep the good work !!
(hi Loren, I am one of the Toulouse guy: it was nice meeting you !!)

Mathias

Loren,

I read and re-read this column several times over the past few days and I’m still confused. I regularly use indexing in MatLab and find that it very powerful tool in writing compact, easy to understand code.

But this xy option is very confusing to me. I had never previously noticed the xy option in the axis function and based on this column, I took some time to try to understand the value or benefit of that option. I also tried to follow your example regarding ndgrid and found myself bumping up against one of the few serious limitations within MatLab. That is MatLab’s poor capability regarding table lookups. In the past when I’ve tried to figure out how to use interpn, I’ve been tripped up by the example in the function reference page that uses ndgrid. There is something fundamental about the ndgrid function that I’m not getting and I wonder if it is related to this ij vs xy concept.

I’m with Jessee above, pick a standard and stick with it. Just because MatLab can provide alternate ways to do things doesn’t mean that there is a benefit to the alternate way. My experience is that the indexing method is widely used in MatLab so that should be the standard.

Maybe you need to write a detailed column that goes beyond the single example in the function reference page for ndgrid and also provides a proper description of the ndgrid function. e.g., the description says that it transforms the domain specified by the vectors into arrays. But, it doesn’t say how they are transformed.

Anyway, after all this, I still don’t understand what the significance is for this xy indexing.

I was most interested in the use of the commands image and imagesc to plot the values of items in matrices.

I had been using pcolor along with ‘shading flat’ to achieve almost the same effect. The problem with doing this is that in plotting the contents of an n x n array, you get a figure with an (n-1)x(n-1) array of elements, the last row and column being ignored.

I would like to use image instead of pcolor for my applications (using ‘axis xy’ to preserve orientation), but for one small hitch. pcolor treats NaN’s as blanks whereas image and imagesc treat them as zeros. I need them to be treated as blanks, so I keep using pcolor. A further problem with using pcolor is that I don’t find the ticklabels line up nicely with the centers of the colorblocks as they do in the magic square example above. Loren, please help. is there anything I can do?

I realize that one workaround is to add an extra row and column to my array of data, but this seems like an ugly hack.

More details: all the data in my matrix is positive integers, so another workaround is for me to convert all the NaN’s to zeros before using ‘image’. The problem now becomes that the zeros (which I want to ignore) show up in the colorbar.

Thanks,
Roy

I have exactly the same problem as Roy Goodman has. I’m surprised that Roy’s email was posted only recently (I started using Matlab a year ago). Most of the matrix data I want to display have some NaN elements in them. Is it possible to add another ‘property’ and ‘value’ pair to specify the color for displaying the NaN elements in a matrix?

Thanks,
Xingong

Guys-

You might try this code (using the opengl renderer, which MATLAB will do automatically with the transparency – though there are bugs in various opengl drivers and they don’t all look the same).

A = magic(3)
AA  = A
AA(1) = NaN
imalpha = ones(size(A));
h = image(AA), colorbar
colormap(jet(9))
imalpha(isnan(AA)) = 0
set(h,'alphadata',imalpha)

If your picture doesn’t look right, close your figure and use this command first:

opengl software

and then retry. The graphics will be a bit slower but will tend to overcome hardware opengl issues typically.

–Loren

Glad to find this discussion: whilst meshgrid and its family are excellent starting points for regridding (2D) “images”, when volumes or time varying volumes appear, then ndgrid must be used. OK, so far, but then we find that stream3, streamtube etc require meshgrid. Meshgrid for 3D data (e.g. look at “wind” in the examples)? Why oh why oh why?

So, here’s the solution I request.

If GIVEN some volume data (e.g., “wind”) which has meshgrid orientation, give me

mesh2nd(x,y,z,u,v,w)

which flips round (or regrids) the x,y and z, and ALSO suitably transposes the u,v,w, so it matches the transformed x,y & z.

Either today is a fuzzy Friday for me, or this is not a simple as it may sound.

Cheers,

Hi Loren!,

I have a problem.SO,was going through this post. I still dont have an answer so i post it here.

I have a 2 dimensional matrix which i read from a file.There are multiple files, sigma1, sigma2 and so on,
I read it from the file and assign it to a local variable ( a 3 dimensional matrix) and reassign this another variable, which i intend to use in the actual code. But i have difficulties in indexing. I am sort of confused.

My question, can i use something similar to ## in C to append a number to a variable, for example


MU##1 = MU;  %assign matrix MU to MU1;

My code is here anyways



for i =1:N  % for each state of nature wi
   for j = 1:M,
         mu = strcat('K:\MU',int2str(i),'.txt');
         sig = strcat('K:\SIGMA',int2str(i),'.txt'); 
    data_mu = load(mu);
    data_sig = load(sig);
     MU(i,:,j) = data_mu(:,j); % load different columns to 3d ARRAY
     SIGMA(i,:,j) = data_sig(:,j);
   end
end

MU1 = MU(1,:,:); % load matrix of first dimension.
SIGMA1 = SIGMA(1,:,:);




Ex : sigma = [2 0;0 0.5];

Thanks !

These postings are the author's and don't necessarily represent the opinions of MathWorks.