Skip to content

Meshgrid enhancements (>2-D, sparse grids, matrix indexing) #192

Merged
merged 5 commits into from Jul 18, 2012

5 participants

@charris charris and 1 other commented on an outdated diff Feb 1, 2012
numpy/lib/function_base.py
Parameters
----------
- x, y : ndarray
- Two 1-D arrays representing the x and y coordinates of a grid.
+ x1, x2,..., xn : array_like
+ 1-D arrays representing the coordinates of a grid.
+ indexing : {'xy', 'ij'}, optional
+ Cartesian ('xy', default) or matrix ('ij') indexing of output.
+ See Notes for more details.
+ sparse : bool, optional
+ If True a sparse grid is returned in order to conserve memory.
+ Default is False.
+ copy : bool, optional
+ If False, a view into the original arrays are returned in
+ order to conserve memory. Default is True. Please note that
+ ``sparse=False, copy=False`` will likely return non-contiguous arrays.
+ Furthermore, more than one element of a broadcasted array may refer to
@charris
NumPy member
charris added a note Feb 1, 2012

broadcast, not broadcasted. Although languages do evolve ;)

@rgommers
NumPy member
rgommers added a note Feb 5, 2012

fixed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@charris charris commented on the diff Feb 1, 2012
numpy/lib/function_base.py
- return `X`, `Y` where `X` and `Y` are ``(Ny, Nx)`` shaped arrays
- with the elements of `x` and y repeated to fill the matrix along
- the first dimension for `x`, the second for `y`.
+ X1, X2,..., XN : ndarray
+ For vectors `x1`, `x2`,..., 'xn' with lengths ``Ni=len(xi)`` ,
+ return ``(N1, N2, N3,...Nn)`` shaped arrays if indexing='ij'
+ or ``(N2, N1, N3,...Nn)`` shaped arrays if indexing='xy'
+ with the elements of `xi` repeated to fill the matrix along
+ the first dimension for `x1`, the second for `x2` and so on.
+
+ Notes
+ -----
+ This function supports both indexing conventions through the indexing keyword
+ argument. Giving the string 'ij' returns a meshgrid with matrix indexing,
+ while 'xy' returns a meshgrid with Cartesian indexing. In the 2-D case
+ with inputs of length M and N, the outputs are of shape (N, M) for 'xy'
@charris
NumPy member
charris added a note Feb 1, 2012

Maybe explain this with a connection to image plots, where the 'x' typically runs left to right and is the 'fast' index. Or is that what this is about. Where would one use 'ij' ?

@teoliphant
NumPy member
teoliphant added a note Feb 1, 2012

I agree. I find the "matrix indexing" versus "Cartesian indexing" description hard to understand. I think you are talking about "image" conventions versus "plotting" conventions. Is that correct?

@rgommers
NumPy member
rgommers added a note Feb 5, 2012

Correct, image convention vs. just standard array/matrix indexing. Since this is the most confusing part apparently (see also discussion on this point at http://projects.scipy.org/numpy/ticket/966), I'm tempted to just leave out the indexing keyword after all. This seems to be confusing for Matlab users too, see for example the comments at http://blogs.mathworks.com/loren/2007/06/21/indexing-terminology/.

There really isn't an ideal solution here.

Note that mgrid and ogrid use 'ij', while currently meshgrid uses 'xy':

In [35]: mgrid[0:2, 3:5]
Out[35]: 
array([[[0, 0],
        [1, 1]],

       [[3, 4],
        [3, 4]]])

In [36]: meshgrid([0, 1], [3, 4])
Out[36]: 
[array([[0, 1],
       [0, 1]]), array([[3, 3],
       [4, 4]])]
@charris
NumPy member
charris added a note Feb 5, 2012

Maybe call ir 'image' indexing? I find in practice it is easier to settle on a single convention ('ij'), always put x in the first index, and just transpose for showing images. Mixing the conventions leads to all sorts of confusion.

@rgommers
NumPy member
rgommers added a note Feb 5, 2012

Only using 'ij' would be best probably, but since currently meshgrid uses 'xy' we can't do that.

@charris
NumPy member
charris added a note Feb 5, 2012

Oops, see, I already got confused ;) I think a different choice of names would clarify things, 'xy' seems ok, 'standard' would be another option, and then maybe 'image' for the second choice, with a short explanation (images are displayed left-right, top-bottom) and a translation for Matlab users.

@rgommers
NumPy member
rgommers added a note May 28, 2012

ij --> image sounds OK to me. Although I forgot the details by now. With added explanation it should work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@charris charris commented on the diff Feb 1, 2012
numpy/lib/function_base.py
+ sparse = kwargs.get('sparse', False)
+ indexing = kwargs.get('indexing', 'xy')
+ if not indexing in ['xy', 'ij']:
+ raise ValueError("Valid values for `indexing` are 'xy' and 'ij'.")
+
+ s0 = (1,) * ndim
+ output = [x.reshape(s0[:i] + (-1,) + s0[i + 1::]) for i, x in enumerate(args)]
+
+ shape = [x.size for x in output]
+
+ if indexing == 'xy':
+ # switch first and second axis
+ output[0].shape = (1, -1) + (1,)*(ndim - 2)
+ output[1].shape = (-1, 1) + (1,)*(ndim - 2)
+ shape[0], shape[1] = shape[1], shape[0]
+
@charris
NumPy member
charris added a note Feb 1, 2012

So 'xy' indexing only affects the first two axis?

@rgommers
NumPy member
rgommers added a note Feb 5, 2012

yes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@charris charris and 1 other commented on an outdated diff Feb 1, 2012
numpy/lib/tests/test_function_base.py
+ z = [8, 9]
+ assert_(meshgrid(x, y)[0].shape == (4, 3))
+ assert_(meshgrid(x, y, indexing='ij')[0].shape == (3, 4))
+ assert_(meshgrid(x, y, z)[0].shape == (4, 3, 2))
+ assert_(meshgrid(x, y, z, indexing='ij')[0].shape == (3, 4, 2))
+
+ assert_raises(ValueError, meshgrid, x, y, indexing='notvalid')
+
+ def test_sparse(self):
+ [X, Y] = meshgrid([1, 2, 3], [4, 5, 6, 7], sparse=True)
+ assert_(all(X == array([[1, 2, 3]])))
+ assert_(all(Y == array([[4],
+ [5],
+ [6],
+ [7]])))
+
@charris
NumPy member
charris added a note Feb 1, 2012

Any reason not to put that on a single line?

@rgommers
NumPy member
rgommers added a note Feb 5, 2012

not really, changed that now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@teoliphant
NumPy member

It seems that this PR can be merged. Confusion in the naming can be improved later (and already exists between the default mgrid and meshgrid conventions).

@rgommers
NumPy member

Would be better to fix it before/when merging imho, otherwise it will simply be forgotten. Sorry I haven't made the time to finish this off yet.

@lukecampbell

Looks really good, can't wait for this to be merged.

@teoliphant teoliphant merged commit 0b2bfa9 into numpy:master Jul 18, 2012
@teoliphant teoliphant added a commit to teoliphant/numpy that referenced this pull request Jul 18, 2012
@teoliphant teoliphant BUG: Fix some tests in PR #192 5b4e61b
@rgommers rgommers deleted the rgommers:meshgrid3d branch Jun 3, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.