NumPy Meshgrid – A Simple Guide with Video

In Python, the numpy.meshgrid() function turns coordinate vectors into coordinate matrices

Figure: A simple illustration of the workings of np.meshgrid().

What’s the purpose of np.meshgrid()?

The grid-like coordinate matrices separate the values for each dimension and are used widely in matrix manipulation, data visualization, and machine learning

Here is the argument table of numpy.meshgrid().

If it sounds great to you, please continue reading, and you will fully understand the numpy.meshgrid() function through Python code snippets and vivid visualization.

  • Concretely, I will introduce its syntax and arguments
  • Then, you will learn some basic examples of this function.
  • Finally, I will address three top questions about numpy.meshgrid(), including numpy.meshgrid() indexing, numpy.meshgrid() sparse, and numpy.meshgrid() vs. numpy.ogrid() vs. numpy.mgrid().

You can find all the codes in this tutorial here.

Syntax and Arguments

Here is the syntax of numpy.meshgrid():

# Syntax
numpy.meshgrid(*xi[, copy=True[, sparse=False[, indexing='xy']]])

Here is the argument table of numpy.meshgrid():

ArgumentAcceptDescription
*xi(= x1, x2,…, xn)array_like1-D arrays representing the coordinates of a grid.
indexing{'xy', 'ij'}, optionalCartesian ('xy', default) or matrix ('ij') indexing of output.
sparsebool, optionalDefault = False.
False => Dense Grid Output;
True => Sparse Grid output.
copybool, optionalDefault = True. If False, a view into the original arrays are returned in order to conserve memory.

I will further explain the indexing and sparse arguments with examples later πŸ™‚

The output of numpy.meshgrid() function is coordinate matrices with the same number as the input coordinate vectors, representing one dimension each. 

In the 2-D case with inputs of length M and N, the outputs are of shape (N, M) for 'xy' Cartesian indexing and (M, N) for 'ij' Matrix indexing. In the 3-D case with inputs of length M, N and P, outputs are of shape (N, M, P) for 'xy' indexing and (M, N, P) for 'ij' indexing.

Basic Examples

By default, the np.meshgrid() function will turn all input coordinate vectors into the same amount of coordinate Sparse matrices using the Cartesian indexing.

Next, I will show you the Python code to turn two coordinate vectors, x and y, into two coordinate matrices, xx and yy. We start by importing numpy as np, assigning coordinate vectors x and y, and then using the numpy.meshgrid() function to get coordinate matrices.

import numpy as np

x = np.linspace(0, 5, 5)
y = np.linspace(5, 10, 5)
xx, yy = np.meshgrid(x, y)
print('Coordinate Vector - x:')
print(x)
print('\nCoordinate Vector - y:')
print(y)
print('\nCoordinate Matrix - xx:')
print(xx)
print('\nCoordinate Matrix - yy:')
print(yy)

Output:

From the ouput, we can see that adding xx and yy in an element-wise way will result a grid-like coordinate structure! 

Intuitively, in this two-vector-and-Cartesian-indexing case, you can consider the vector x as the x-axis vector and the vector y as the y-axis vector.

If you put the vector x and vector y together to form coordinate pairs, the values in the matrix xx will be the x-axis values for all coordinate pairs and the values in the matrix yy will be the y-axis values for all coordinate pairs.

Seen pictorially, Here is the visualiztion for our basic example code above.

The left plot shows the coordinate vectors x and y. The green dots represent the vector x with zero y-axis values. The blue stars represent the vector y with zero x-axis values. The right plot shows the coordinate pairs of vectors x and y.

Code for the above Visualization:

import matplotlib.pyplot as plt


# coordinate vectors
plt.plot(x, np.zeros_like(x), color='g', marker='o', linestyle='none')
plt.plot(np.zeros_like(y), y, color='b', marker='*', linestyle='none')

# coordinate pairs
plt.scatter(xx, yy, color='r')
plt.show()

np.meshgrid() indexing

In our basic example, we have not yet passed any arguments to the numpy.meshgrid() function.

In this part, I will explain the indexing argument and show you the difference between using the Cartesian indexing and Matrix indexing. Hold tight!

For your quick reference, here is the argument table of numpy.meshgrid():

Next, I will show you the two indexing ways in Python code. We start by importing numpy as np, assigning coordinate vectors x and y, and then using the numpy.meshgrid() function with different indexing arguments respectively.

import numpy as np

# Cartesian Indexing (Default Indexing Method)
print('Cartesian Indexing (Default Indexing Method)\n')
x = np.linspace(0, 3, 3)
y = np.linspace(2, 4, 2)
xx, yy = np.meshgrid(x, y, indexing='xy')
# Same as:
# xx, yy = np.meshgrid(x, y)
print('Coordinate Vector - x:')
print(x)
print('Coordinate Vector - y:')
print(y)
print('Coordinate Matrix - xx:')
print(xx)
print('Coordinate Matrix - yy:')
print(yy)


# Matrix Indexing
print('-'*85)
print('Matrix Indexing\n')
x = np.linspace(0, 3, 3)
y = np.linspace(2, 4, 2)
xx, yy = np.meshgrid(x, y, indexing='ij')
print('Coordinate Vector - x:')
print(x)
print('Coordinate Vector - y:')
print(y)
print('Coordinate Matrix - xx:')
print(xx)
print('Coordinate Matrix - yy:')
print(yy)

Output:

The output of numpy.meshgrid() function is coordinate matrices with the same number as the input coordinate vectors, representing one dimension each. 

  • In the 2-D case with inputs of length M and N, the outputs are of shape (N, M) for 'xy' Cartesian indexing and (M, N) for 'ij' Matrix indexing.
  • In the 3-D case with inputs of length M, N and P, outputs are of shape (N, M, P) for 'xy' indexing and (M, N, P) for 'ij' indexing.

np.meshgrid() sparse

In this part, I will show you the difference between a dense grid output with the argument sparse = False and a sparse grid output with the argument sparse = True.

For example, We start by importing numpy as np, assigning coordinate vectors x and y, and then using the numpy.meshgrid() function with different sparse argument respectively.

By the way, I feel more comfortable with the Cartesian indexing method. Therefore, I will use it as the indexing method for the rest examples:)

Here is the code:

import numpy as np

# sparse = False (Default)
print('sparse=False:')
x = np.linspace(0, 3, 3)
y = np.linspace(2, 4, 2)
xx, yy = np.meshgrid(x, y, sparse=False)
# Same as:
# xx, yy = np.meshgrid(x, y)
print('Coordinate Vector - x:')
print(x)
print('Coordinate Vector - y:')
print(y)
print('Coordinate Matrix - xx:')
print(xx)
print('Coordinate Matrix - yy:')
print(yy)

# sparse = True
print('-'*85)
print('sparse=True:')
x = np.linspace(0, 3, 3)
y = np.linspace(2, 4, 2)
xx, yy = np.meshgrid(x, y, sparse=True)
# Same as:
# xx, yy = np.meshgrid(x, y)
print('Coordinate Vector - x:')
print(x)
print('Coordinate Vector - y:')
print(y)
print('Coordinate Matrix - xx:')
print(xx)
print('Coordinate Matrix - yy:')
print(yy)

Output:

From the ouptut, we can see the difference between a sparse grid output (sparse=True) and a dense grid ouput (sparse=False) is literally the density of the coordinate matrix. 

Therefore, when you want a simpler way to pair coordinate matrixes, you can go with the default sparse=False and get a dense grid output. 

np.meshgrid() vs. np.ogrid() vs. np.mgrid()

Last, let’s check out and compare two other grid-related numpy.ogrid and numpy.mgrid.

  • Functionally, the numpy.ogrid is equivalent with numpy.meshgrid with its argument sparse=True.
  • The numpy.mgrid represents the numpy.meshgrid with its argument sparse=False.

On top of that, numpy.ogrid and numpy.mgrid use the Matrix indexing method. Bad news for a Cartesian indexing fan like me πŸ™

Let’s look at the comparison between np.meshgrid with sparse=True and indexing='ij' and np.ogrid.

import numpy as np

# numpy.meshgrid with sparse=True + indexing='ij'
print('numpy.meshgrid with sparse=True + indexing=\'ij\':')
x = np.arange(0, 3)
y = np.arange(2, 4)
xx, yy = np.meshgrid(x, y, sparse=True, indexing='ij')

print('Coordinate Vector - x:')
print(x)
print('Coordinate Vector - y:')
print(y)
print('Coordinate Matrix - xx:')
print(xx)
print('Coordinate Matrix - yy:')
print(yy)

# numpy.ogrid
print('-'*85)
print('numpy.ogrid:')
xx, yy = np.ogrid[0:3, 2:4]

print('Coordinate Vector - x:')
print(x)
print('Coordinate Vector - y:')
print(y)
print('Coordinate Matrix - xx:')
print(xx)
print('Coordinate Matrix - yy:')
print(yy)

Output:

I am glad that in this way, you guys are the same!

Now, let’s check out the difference between np.meshgrid with sparse=False and np.mgrid.

import numpy as np

# numpy.meshgrid with sparse=True + indexing='ij'
print('numpy.meshgrid with sparse=False + indexing=\'ij\':')
x = np.arange(0, 3)
y = np.arange(2, 4)
xx, yy = np.meshgrid(x, y, sparse=False, indexing='ij')

print('Coordinate Vector - x:')
print(x)
print('Coordinate Vector - y:')
print(y)
print('Coordinate Matrix - xx:')
print(xx)
print('Coordinate Matrix - yy:')
print(yy)

# numpy.mgrid
print('-'*85)
print('numpy.ogrid:')
xx, yy = np.mgrid[0:3, 2:4]

print('Coordinate Vector - x:')
print(x)
print('Coordinate Vector - y:')
print(y)
print('Coordinate Matrix - xx:')
print(xx)
print('Coordinate Matrix - yy:')
print(yy)

Output:

I am glad that in this way, you guys are also the same!

In conclusion, 

  • numpy.meshgrid with sparse=True + indexing='ij'  == numpy.ogrid
  • numpy.meshgrid with spares=False + indexing='ij' == numpy.mgrid

Summary

That’s it for our np.meshgrid() article. 

We learned about its syntax, arguments, and basic examples. 

We also worked on the top three questions about the np.meshgrid() function, ranging from numpy.meshgrid indexing, numpy.meshgrid sparse, and numpy.meshgrid vs. numpy.ogrid vs. numpy.mgrid

Hope you enjoy all this and happy coding!