Repository: scikit-image/scikit-image

Issue:
find_contours returns (y,x) instead of (x,y) pairs
The API doc says for the return value "Each contour is an ndarray of shape `(n, 2)`, consisting of n `(x, y)` coordinates along the contour."

A small test case, with input:
![figure_4](https://cloud.githubusercontent.com/assets/530988/4217168/2ceec576-38e4-11e4-8b27-62839077635e.png)

```
def testImage():
    n = 10
    coord = np.ones((n,n))

    r = n*0.4
    y,x = np.ogrid[-r: r+1, -r: r+1]
    mask = x**2+y**2 <= r**2

    coord[mask] = -coord[mask]
    coord[coord>0] = np.nan
    # make it non-symmetric
    coord[4,0] = np.nan

    r = ~np.isnan(coord)
    return np.hstack((r,r))

import skimage.measure
contours = skimage.measure.find_contours(testImage(), 0.99)
print contours
# output:
 [array([[ 0.,  4.],
       [ 1.,  5.],
       [ 1.,  6.],
       [ 1.,  6.],
       [ 2.,  7.],
       [ 2.,  7.],
       [ 3.,  7.],
       [ 4.,  8.],
       [ 4.,  8.],
       [ 4.,  8.],
       [ 5.,  7.],
       [ 6.,  7.],
       [ 6.,  7.],
       [ 7.,  6.],
       [ 7.,  6.],
       [ 7.,  5.],
       [ 8.,  4.],
       [ 8.,  4.],
       [ 8.,  4.],
       [ 7.,  3.],
       [ 7.,  2.],
       [ 7.,  2.],
       [ 6.,  1.],
       [ 6.,  1.],
       [ 5.,  1.],
       [ 4.,  1.],
       [ 3.,  1.],
       [ 2.,  1.],
       [ 2.,  1.],
       [ 1.,  2.],
       [ 1.,  2.],
       [ 1.,  3.],
       [ 0.,  4.]]), array([[  0.,  14.],
       [  1.,  15.],
       [  1.,  16.],
       [  1.,  16.],
       [  2.,  17.],
       [  2.,  17.],
       [  3.,  17.],
       [  4.,  18.],
       [  4.,  18.],
       [  4.,  18.],
       [  5.,  17.],
       [  6.,  17.],
       [  6.,  17.],
       [  7.,  16.],
       [  7.,  16.],
       [  7.,  15.],
       [  8.,  14.],
       [  8.,  14.],
       [  8.,  14.],
       [  7.,  13.],
       [  7.,  12.],
       [  7.,  12.],
       [  6.,  11.],
       [  6.,  11.],
       [  5.,  11.],
       [  4.,  11.],
       [  3.,  11.],
       [  2.,  11.],
       [  2.,  11.],
       [  1.,  12.],
       [  1.,  12.],
       [  1.,  13.],
       [  0.,  14.]])]
```

You can see clearly that the x-coordinate is actually in the second column and not the first.

Apart from that, why are there consecutive duplicates? Should I open a separate issue for that?



Discussion:
I'm not sure about the duplicates, but the coordinates is expected, if marred by unfortunate nomenclature: skimage (almost) always works in numpy indexing space. That means that the first coordinate is rows and the second columns.

@jni, but then the doc string is wrong, because it says (x, y)… ?=

Yes, you're probably right. But I read (x, y) exactly as I read (rr, cc). Maybe I shouldn't. =) It's all arbitrary nomenclature!

It is arbitrary nomenclature that causes tremendous amounts of rage!  

I agree the docstring should say either (y, x) or (rr, cc).  An `np.unique` should take care of the dupes.

When I use any function which references coordinates, I understand it's referencing the standard way to view a NumPy array (same for MATLAB): X is the first dimension, which is vertical, while Y is the second dimension which is horizontal. The origin is in the upper left. It's how all 2D arrays are referenced, printed, and visualized. Thus, when handled properly, the current docstring is correct.

To reiterate: If we change this to (y, x) and I had no prior experience with the function, I would enter incorrectly transposed coordinates. (rr, cc) is more correct here, but not ideal because it doesn't intuitively generalize to higher dimensions. We should probably pick a standard for the package and stick to it.

My nomenclature preference is to anchor each spatial dimension to increasing ranks in the N-d array, which corresponds to (x, y, z). Yes, images end up displayed (y, x) in this format, but that's expected behavior. If this is persistently confusing to users, we could do some ASCII art in the docstring to assist, e.g.:

``` python
'''
The dimensional coordinates above use the standard NumPy indexing system, shown below:

o --------> y
|  your
|  image
v
x

'''
```

Nice picture @JDWarner, but the vertical axis is still called `y` when using matplotlib (and almost every plot the user has ever seen)...

cc @ericdill

Let's make it explicit in the docstring with `(i, j, k)` or `(row, column, depth)`.  `x` and `y` are too overloaded already.


Resolving patch:
diff --git a/skimage/measure/_find_contours.py b/skimage/measure/_find_contours.py
--- a/skimage/measure/_find_contours.py
+++ b/skimage/measure/_find_contours.py
@@ -35,7 +35,7 @@ def find_contours(array, level,
     -------
     contours : list of (n,2)-ndarrays
         Each contour is an ndarray of shape ``(n, 2)``,
-        consisting of n ``(x, y)`` coordinates along the contour.
+        consisting of n ``(row, column)`` coordinates along the contour.
 
     Notes
     -----


Test patch: