Loren on the Art of MATLAB

Scalar Roulette 4

Posted by Loren Shure,

A while ago, Steve posted an article entitled Functional Design Clunkers on his blog. Well, I have a confession to make too. Have you ever been bitten by the ambiguity in the contour function?

Contents

Two Syntaxes That Can Clash

Here are the two syntaxes that can class for contour:

  • contour(Z,n)
  • contour(Z,v)

From the documentation:

contour(Z,v) draws a contour plot of matrix Z with contour lines at the data values specified in the monotonically increasing vector v. The number of contour levels is equal to length(v). To draw a single contour of level i, use contour(Z,[i i]).

Time for the confession. I thought at the time we were designing contour that asking for a single contour would be rare enough to warrant having the "convenient" syntaxes that could clash. And I even know the work-around for programmers. If they wanted to specify the contour levels, they simply needed some code like this:

         if length(mycontours) == 1
            mycontours(2) = mycontours;
         end
         % now call the contour function

So, why don't I like this now? The code is harder to read, the intent is harder to discern, and it just feels clunky.

Possible Solutions

I can think of a bunch of possible solutions, were we to design the contour function today. These include (but certainly aren't limited to):

  • two functions, 1 for number of contours, 2 for values of contours
  • control number vs. level behavior with param/value pairs or some similar device
  • have one of the inputs (perhaps scalar level number) be in a cell array or some other class that differs from the class for the level values input

Have You Been Bitten?

Has the ambiguity in contour bitten you? Or one in some other MATLAB functionality? What solution do you prefer? Let me know here.


Get the MATLAB code

Published with MATLAB® 7.10

4 CommentsOldest to Newest

I prefer the option no.2.
Something like:

contour(Z,’number’,8);
contour(Z,’levels’,[-4 0 4]);

This would have the advantage to remain compatible with the present syntax, if the 2nd input argument is not a string.

One inconsistency that has tripped me up in the past is the row-wise assignments of the SUBPLOT function. For example, given the command:

subplot(2,2,2)

which, according to the documentation, breaks the the Figure window into an 2-by-2 matrix of axes and selects the 2nd one, we should expect the current axes to match any other 2nd element of any other MATLAB matrix.

A = zeros(2,2); % A 2-by-2 matrix
A(2) = 5; % Change the second element.

These commands put a five in the lower left element, yet the second axes addressed by the above subplot corresponds to the third element in A (the upper right), not the second.

Yes it is documented that the axes are counted row-wise, but why this sudden change from MATLAB column-dominated addressing?

Matt-

Sudden is a funny word in this context – subplot was this way from before I ever used MATLAB so I don’t know why it was designed row-wise. But I can definitely see how the inconsistency causes problems!

–Loren

The second option using param/value pairs seems like the best of those three.

Another option would be that the second argument is always the number of contours and the third argument is always a vector of contour values. As with other functions (like MAX) you could just leave the second input as empty if it isn’t necessary:

contour(Z,n);     % Plots n contours
contour(Z,[],0);  % Plots 1 contour at 0
contour(Z,[],v);  % Plots the contours in vector v

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