Quick answer: np.ogrid creates open coordinate grids whose axes have sparse shapes such as (rows, 1) and (1, columns). NumPy broadcasting combines them inside a calculation, which is useful for masks and formulas without materializing repeated coordinates before they are needed.

NumPy ogrid creates open coordinate grids. Instead of building full two-dimensional coordinate arrays immediately, it returns sparse arrays that broadcast together when you use them in an expression. This makes ogrid useful for masks, distance calculations, image-style indexing, and formulas over rows and columns.
The key idea is shape. For a two-dimensional grid, np.ogrid often returns one array shaped like (rows, 1) and another shaped like (1, columns). NumPy broadcasting then combines them without storing every repeated coordinate. The official NumPy ogrid documentation describes it as an open multi-dimensional mesh-grid.
Use ogrid when the coordinate values are only an intermediate step in a calculation. If you are calculating a mask, radius, distance from a center, or row-column condition, sparse coordinate arrays often express the logic directly while keeping memory use low.
Basic NumPy ogrid Syntax
ogrid uses square-bracket slice syntax, not normal function-call syntax. The slices define the coordinate ranges for each axis. For a 3 by 4 grid, you can create row and column coordinate arrays like this:
import numpy as np
rows, cols = np.ogrid[0:3, 0:4]
print(rows.shape)
print(cols.shape)
print(rows)
print(cols)
The row coordinate has shape (3, 1), and the column coordinate has shape (1, 4). Those shapes are the reason ogrid is memory-friendly compared with dense coordinate grids. The arrays look incomplete by themselves, but they become complete when NumPy broadcasts them inside arithmetic or comparison expressions.
Use ogrid to Build Boolean Masks
A common use case is creating a boolean mask over an array. Because rows and cols broadcast together, you can write expressions that behave as if each cell had its own row and column coordinate.
import numpy as np
array = np.arange(12).reshape(3, 4)
rows, cols = np.ogrid[0:3, 0:4]
mask = rows + cols > 3
print(array[mask])
This selects values whose row index plus column index is greater than three. The same pattern works for diagonal masks, circular masks, and region-of-interest filters. If you are still building comfort with arrays, review the related guide to NumPy arrays in Python.
Use Complex Steps for Evenly Spaced Points
ogrid also supports complex-number step values such as 5j. In slice syntax, that means “create exactly five points” across the interval. This is useful when you want coordinates for plotting or numerical formulas.
import numpy as np
x, y = np.ogrid[-1:1:5j, -1:1:5j]
radius = np.sqrt(x * x + y * y)
print(radius.round(2))
The result broadcasts a vertical x coordinate with a horizontal y coordinate. That lets you calculate a full radius grid while keeping the coordinate inputs sparse. This notation is especially handy for examples where you care about the number of sample points more than the exact step size.

NumPy ogrid vs mgrid
The main difference is that ogrid returns sparse open grids, while mgrid returns dense grids. Dense grids are sometimes easier to inspect, but sparse grids usually use less memory. PythonPool also has a separate guide to NumPy mgrid if you want the dense-grid version.
import numpy as np
open_rows, open_cols = np.ogrid[0:3, 0:4]
dense_rows, dense_cols = np.mgrid[0:3, 0:4]
print(open_rows.shape, open_cols.shape)
print(dense_rows.shape, dense_cols.shape)
For large arrays, this shape difference can be significant. A sparse pair can represent the coordinate system without materializing every repeated row and column value. That does not make mgrid wrong; it simply means each tool fits a different memory and readability tradeoff.
ogrid vs meshgrid and indices
meshgrid() is a flexible function for coordinate matrices, especially when you need explicit dense arrays or control over Cartesian versus matrix indexing. indices() returns dense index grids for an array shape. Use ogrid when sparse broadcasting is enough, and use dense tools when another library expects full coordinate arrays.
import numpy as np
height, width = 4, 5
row, col = np.ogrid[:height, :width]
center_row = (height - 1) / 2
center_col = (width - 1) / 2
mask = (row - center_row) ** 2 + (col - center_col) ** 2 <= 4
print(mask.astype(int))
This circular mask pattern is common in image processing and heatmap-style calculations. For visual output, it pairs naturally with tools such as Matplotlib heatmaps. The important part is that the boolean expression reads like the math: distance from a center point is less than or equal to a radius.

Practical Example With Array Filtering
You can combine ogrid with ordinary NumPy operations to update only part of an array. The mask is calculated from coordinates, then used to assign or extract values.
import numpy as np
matrix = np.arange(25).reshape(5, 5)
row, col = np.ogrid[:5, :5]
upper_triangle = row < col
matrix[upper_triangle] = -1
print(matrix)
This changes values above the main diagonal. The same idea applies to matrix operations, including workflows like matrix addition in Python and summary calculations such as NumPy variance. Coordinate masks are often easier to read than nested loops because the condition is written once for the whole array.
Common Mistakes
The most common mistake is expecting ogrid to return full coordinate matrices. It returns sparse arrays by design. Another mistake is using normal parentheses, such as np.ogrid(0:3, 0:4), which is invalid Python syntax. Use square brackets with slices. Finally, remember that slices follow normal Python stop-exclusive behavior unless you use a complex step such as 5j.
Also be careful when passing sparse grids to APIs outside NumPy. Many NumPy expressions understand broadcasting, but plotting or image libraries may expect dense arrays. If a function complains about shape mismatch, check whether it needs meshgrid(), mgrid, or an explicitly broadcast result.
Conclusion
Use NumPy ogrid when you need coordinate arrays for broadcasting, masks, and grid-based formulas without the memory cost of dense grids. Use mgrid, meshgrid(), or indices() when you explicitly need full coordinate matrices. For many array filtering tasks, ogrid is the cleaner and more efficient starting point.
Read The Shapes First
The shape of each open grid explains the calculation. One axis varies vertically and the other horizontally, so an expression such as rows + cols produces a full result through broadcasting. Inspect shapes before debugging a mask.

Use Slice Syntax Deliberately
ogrid uses square brackets with slices. Normal stop-exclusive ranges are useful for integer coordinates, while a complex step such as 5j requests a fixed number of evenly spaced points. Keep the interval and sampling decision visible in code.
Build Masks Without Nested Loops
A coordinate expression can describe a diagonal, radius, band, or region-of-interest mask once for the whole array. This is often easier to review than nested loops and lets NumPy perform the vectorized operation.

Compare Sparse And Dense Tools
Use ogrid when sparse inputs and broadcasting are enough. Use mgrid or meshgrid when a downstream API requires explicit dense coordinate matrices, or when dense data is small and direct inspection is more useful than memory savings.
Check Memory At The Result
ogrid avoids dense coordinate inputs, but a later expression or broadcast result can still allocate a large array. Estimate output shape and dtype, and avoid assuming that a sparse input makes every downstream operation small.
Validate Mask Shapes
Test one-dimensional and two-dimensional ranges, empty ranges, complex steps, integer boundaries, boolean masks, and assignments. Assert the resulting shape before indexing an array so broadcasting errors are caught at the source.
See the official numpy.ogrid reference and compare mgrid with meshgrid. Related guidance includes heatmaps and array tests.
For related grid calculations, compare dense mgrid output, axis reductions, and heatmap display when choosing a coordinate representation.
Frequently Asked Questions
What does NumPy ogrid do?
np.ogrid creates open, sparse coordinate grids whose axes broadcast together in arithmetic and masking expressions.
What is the difference between ogrid and mgrid?
ogrid returns open grids with sparse axis shapes, while mgrid materializes dense coordinate grids for the requested ranges.
Why does NumPy ogrid return shapes like (rows, 1) and (1, columns)?
Those shapes are designed for broadcasting: one axis varies down rows and the other varies across columns without repeating all coordinates immediately.
When should I use meshgrid instead of ogrid?
Use meshgrid when an API needs explicit coordinate matrices or its indexing options are important; use ogrid when sparse broadcasting is enough for the calculation.