meshgrid & Coordinate Grids
np.meshgrid turns two 1D coordinate vectors into a pair of 2D coordinate arrays that name every point on a rectangular grid, so you can evaluate a function of two variables f(x, y) everywhere at once without loops.
Learn meshgrid & Coordinate Grids in our free NumPy course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…
Part of the free Numpy course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
You'll build grids from x and y vectors, evaluate surfaces in a single vectorized expression, compare indexing='xy' with indexing='ij', and use sparse=True to save memory.
Suppose you have an x-axis [0, 1, 2] and a y-axis [0, 1] . Together they describe a grid of 6 points . np.meshgrid(x, y) hands you two arrays of the same shape: X repeats the x-values across the rows, and Y repeats the y-values down the columns. Read off the same position in both arrays and you get the coordinates of one grid point.
The reason meshgrid exists is so you can evaluate a function at every grid point in one shot. Because X and Y are arrays, any element-wise expression like X**2 + Y**2 is computed for every cell at once, producing a 2D surface of values. This is exactly the data a 3D surface plot or a heatmap needs.
Two keyword arguments tune meshgrid. indexing controls which input varies along which axis. The default 'xy' is Cartesian and gives an output shape of (len(y), len(x)) — ideal for plotting. Switching to 'ij' gives matrix-style indexing with shape (len(x), len(y)) . Separately, sparse=True returns broadcastable arrays instead of full grids to save memory.
Replace the ___ with the function that builds coordinate grids, then evaluate a simple product surface.
Answer: meshgrid . X and Y both have shape (2, 3) , so X * Y is the element-wise product at every grid point.
meshgrid returns two arrays, so a single target throws away the structure:
Mixing the 'xy' and 'ij' conventions swaps the axes of the result.
✅ Fix: pick one convention on purpose — 'xy' for plots, 'ij' for matrix-style math — and check the output shape.
Two full dense grids of a million-by-million points is enormous.
✅ Fix: pass sparse=True so the grids stay 1-by-N and N-by-1 and only broadcast when used.
Build a grid, compute the distance from each grid point to a target, then report the smallest distance — all without loops.
Lesson complete — you can grid the plane!
You can turn two vectors into coordinate arrays with np.meshgrid , evaluate a function over an entire grid in one expression, choose between 'xy' and 'ij' indexing, and shrink memory with sparse=True .
🚀 Up next: Repeating Arrays — build patterns and constants with np.tile and np.repeat .
Practice quiz
How many arrays does np.meshgrid(x, y) return?
- Two 2D coordinate arrays
- One flat array
- Three arrays
- A single scalar
Answer: Two 2D coordinate arrays. meshgrid returns two arrays, conventionally X and Y, for the grid coordinates.
What does the X output of np.meshgrid hold?
- The y-coordinate of each point
- The x-coordinate of each grid point
- Random noise
- The distances
Answer: The x-coordinate of each grid point. X holds the x-coordinate at every grid cell; Y holds the y-coordinate.
For x=[0,1,2] and y=[0,1], what shape do X and Y have (default 'xy')?
- (3, 2)
- (6,)
- (2, 3)
- (3, 3)
Answer: (2, 3). Default 'xy' gives shape (len(y), len(x)) = (2, 3).
Why does meshgrid let you evaluate f(x, y) with no loops?
- It compiles a loop secretly
- It only works on scalars
- It caches values
- X and Y are arrays, so element-wise expressions cover every cell at once
Answer: X and Y are arrays, so element-wise expressions cover every cell at once. Because X and Y are arrays, one expression like X**2 + Y**2 covers the whole grid.
What does the default indexing='xy' produce versus indexing='ij'?
- 'xy' shape (len(y), len(x)); 'ij' shape (len(x), len(y))
- Both give the same shape
- 'xy' is 1D, 'ij' is 3D
- 'xy' reverses the values
Answer: 'xy' shape (len(y), len(x)); 'ij' shape (len(x), len(y)). 'xy' is Cartesian (len(y), len(x)); 'ij' is matrix-style (len(x), len(y)).
What does sparse=True return instead of full dense grids?
- Nothing
- Broadcastable arrays of shape (1, len(x)) and (len(y), 1)
- A flattened list
- The original vectors unchanged
Answer: Broadcastable arrays of shape (1, len(x)) and (len(y), 1). sparse=True returns broadcastable 1xN and Nx1 arrays that save memory.
For x=[1,2,3], y=[10,20], X, Y = np.meshgrid(x, y); what is X * Y?
Element-wise product at each grid point gives [[10 20 30] [20 40 60]].
What goes wrong if you write grid = np.meshgrid(x, y) with one target?
- grid becomes a list of two arrays, not X
- It raises a SyntaxError
- x and y are deleted
- It returns a scalar
Answer: grid becomes a list of two arrays, not X. A single target captures the list of both arrays; unpack as X, Y instead.
Why does sparse=True save memory on large grids?
- It deletes the data
- It uses integers only
- The coordinate values are never physically duplicated
- It stores to disk
Answer: The coordinate values are never physically duplicated. Broadcastable grids avoid duplicating the values across the full grid.
Which dense slicing shortcut is the equivalent of meshgrid(indexing='ij')?
- np.linspace
- np.arange
- np.mgrid
- np.zeros
Answer: np.mgrid. np.mgrid is the dense, slicing-based equivalent of meshgrid with 'ij' indexing.