You can use np.mgrid for this, it's often more convenient than np.meshgrid because it creates the arrays in one step:

import numpy as np
X,Y = np.mgrid[-5:5.1:0.5, -5:5.1:0.5]

For linspace-like functionality, replace the step (i.e. 0.5) with a complex number whose magnitude specifies the number of points you want in the series. Using this syntax, the same arrays as above are specified as:

X, Y = np.mgrid[-5:5:21j, -5:5:21j]

You can then create your pairs as:

xy = np.vstack((X.flatten(), Y.flatten())).T

As @ali_m suggested, this can all be done in one line:

xy = np.mgrid[-5:5.1:0.5, -5:5.1:0.5].reshape(2,-1).T

Best of luck!

Answer from farenorth on Stack Overflow
🌐
NumPy
numpy.org › doc › stable › reference › generated › numpy.linspace.html
numpy.linspace — NumPy v2.4 Manual
>>> import matplotlib.pyplot as plt >>> N = 8 >>> y = np.zeros(N) >>> x1 = np.linspace(0, 10, N, endpoint=True) >>> x2 = np.linspace(0, 10, N, endpoint=False) >>> plt.plot(x1, y, 'o') [<matplotlib.lines.Line2D object at 0x...>] >>> plt.plot(x2, y + 0.5, 'o') [<matplotlib.lines.Line2D object at 0x...>] >>> plt.ylim([-0.5, 1]) (-0.5, 1) >>> plt.show()
🌐
NumPy
numpy.org › devdocs › reference › generated › numpy.linspace.html
numpy.linspace — NumPy v2.5.dev0 Manual
>>> import matplotlib.pyplot as plt >>> N = 8 >>> y = np.zeros(N) >>> x1 = np.linspace(0, 10, N, endpoint=True) >>> x2 = np.linspace(0, 10, N, endpoint=False) >>> plt.plot(x1, y, 'o') [<matplotlib.lines.Line2D object at 0x...>] >>> plt.plot(x2, y + 0.5, 'o') [<matplotlib.lines.Line2D object at 0x...>] >>> plt.ylim([-0.5, 1]) (-0.5, 1) >>> plt.show()
🌐
DataCamp
datacamp.com › tutorial › how-to-use-the-numpy-linspace-function
How to Use the NumPy linspace() Function | DataCamp
April 5, 2024 - import numpy as np # Create an ... Step Size [-5. -1.66666667 1.66666667 5. ] Step Size 3.3333333333333335 · linspace() is also useful for generating multi-dimensional arrays....
🌐
GeeksforGeeks
geeksforgeeks.org › python › numpy-linspace
NumPy linspace() Method | Create Evenly Spaced Array - GeeksforGeeks
February 14, 2026 - np.linspace(0, 1, num=25) generates 25 evenly spaced values between 0 and 1. .reshape(5, 5) converts the 1D array into a 2D array with 5 rows and 5 columns. Comment · Article Tags: Article Tags: Misc · Python · Python-numpy · Python ...
🌐
Real Python
realpython.com › np-linspace-numpy
np.linspace(): Create Evenly or Non-Evenly Spaced Arrays – Real Python
December 1, 2023 - In this tutorial, you'll learn how to use NumPy's np.linspace() effectively to create an evenly or non-evenly spaced range of numbers. You'll explore several practical examples of the function's many uses in numerical applications.
🌐
Note.nkmk.me
note.nkmk.me › home › python › numpy
NumPy: arange() and linspace() to generate evenly spaced values | note.nkmk.me
February 2, 2024 - 8. 6. 4. 2.] print(np.linspace(0, 10, 5, endpoint=False)[::-1]) # [8. 6. 4. 2. 0.] print(np.flip(np.linspace(0, 10, 5, endpoint=False))) # [8. 6. 4. 2. 0.] ... To create multi-dimensional arrays, use the reshape() method, since neither np.arange() nor np.linspace() have an argument to specify the shape.
🌐
IncludeHelp
includehelp.com › python › is-there-a-multi-dimensional-version-of-arrange-linspace-in-numpy.aspx
Python - Is there a multi-dimensional version of arange/linspace in numpy?
October 9, 2023 - # Import numpy import numpy as np # Using linspace method res = np.linspace(2.0, 3.0, num=5) # Display result print("Result:\n",res,"\n")
🌐
Problem Solving with Python
problemsolvingwithpython.com › 05-NumPy-and-Arrays › 05.04-Array-Creation
Array Creation - Problem Solving with Python
The np.linspace() function is useful for creating an array of regularly spaced numbers where the spacing is not known, but the number of values is.
Find elsewhere
🌐
Python Guides
pythonguides.com › python-numpy-linspace
NumPy's Linspace Function In Python
May 16, 2025 - In this example, I used linspace to create a time array for digital audio at CD quality (44.1 kHz). Another common use is for data visualization of real-world data: import numpy as np import matplotlib.pyplot as plt # Average monthly temperatures for New York (°F) months = np.linspace(1, 12, 12) nyc_temps = [33, 35, 43, 54, 65, 74, 79, 77, 70, 58, 48, 38] # Average monthly temperatures for Los Angeles (°F) la_temps = [59, 60, 62, 64, 68, 72, 76, 77, 76, 71, 65, 59] plt.figure(figsize=(10, 6)) plt.plot(months, nyc_temps, 'b-o', label='New York') plt.plot(months, la_temps, 'r-o', label='Los Angeles') plt.xticks(months, ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']) plt.ylabel('Temperature (°F)') plt.title('Average Monthly Temperatures in Major US Cities') plt.grid(True) plt.legend() plt.show()
🌐
NumPy
numpy.org › doc › 2.1 › reference › generated › numpy.linspace.html
numpy.linspace — NumPy v2.1 Manual
>>> import matplotlib.pyplot as plt >>> N = 8 >>> y = np.zeros(N) >>> x1 = np.linspace(0, 10, N, endpoint=True) >>> x2 = np.linspace(0, 10, N, endpoint=False) >>> plt.plot(x1, y, 'o') [<matplotlib.lines.Line2D object at 0x...>] >>> plt.plot(x2, y + 0.5, 'o') [<matplotlib.lines.Line2D object at 0x...>] >>> plt.ylim([-0.5, 1]) (-0.5, 1) >>> plt.show()
🌐
Fritz ai
heartbeat.fritz.ai › home › blog › exploring numpy’s linspace() function
Exploring NumPy’s linspace() function - Fritz ai
September 15, 2023 - The np.linspace() function has the word space in its name; however, it doesn’t accept an explicit argument defining the space between every 2 numbers. The space, or more meaningful step, is calculated indirectly using the num argument.
🌐
NumPy
numpy.org › doc › stable › reference › generated › numpy.arange.html
numpy.arange — NumPy v2.4 Manual
>>> np.arange(0, 5, 0.5, dtype=int) array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) >>> np.arange(-3, 3, 0.5, dtype=int) array([-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8]) In such cases, the use of numpy.linspace should be preferred.
🌐
NumPy
numpy.org › doc › 2.3 › reference › generated › numpy.linspace.html
numpy.linspace — NumPy v2.3 Manual
>>> import matplotlib.pyplot as plt >>> N = 8 >>> y = np.zeros(N) >>> x1 = np.linspace(0, 10, N, endpoint=True) >>> x2 = np.linspace(0, 10, N, endpoint=False) >>> plt.plot(x1, y, 'o') [<matplotlib.lines.Line2D object at 0x...>] >>> plt.plot(x2, y + 0.5, 'o') [<matplotlib.lines.Line2D object at 0x...>] >>> plt.ylim([-0.5, 1]) (-0.5, 1) >>> plt.show()
🌐
Enterprise DNA
blog.enterprisedna.co › numpy-linspace
Numpy.linspace() in Python: A Guide To Create Arrays – Master Data Skills + AI
NumPy’s linspace function is frequently used in physics simulations, especially when dealing with problems that involve continuous change over time or space. By creating a range of evenly spaced values, we can simulate the continuous nature of physical quantities.
🌐
TutorialsPoint
tutorialspoint.com › numpy › numpy_linspace_function.htm
Numpy linspace() Function
Numpy 2D Array - [[ 1. 1.81818182 2.63636364 3.45454545] [ 4.27272727 5.09090909 5.90909091 6.72727273] [ 7.54545455 8.36363636 9.18181818 10. ]] Negative values can be used as arguments in the numpy.linspace() function to create arrays that include negative numbers within the specified range. In the following example, we have created an array with 16 equally spaced values between -5 and 5, then reshape it into a 4x4 matrix − · import numpy as np # Generating 16 equally spaced values between -5 and 5 array_1d = np.linspace(-5, 5, 16) # Reshaping into a 2D array (4 rows and 4 columns) array_2d = array_1d.reshape(4, 4) print("Numpy 2D Array -\n", array_2d)
Top answer
1 of 3
4
In [4]: xstep = np.linspace(0, 1, 2)

In [5]: ystep = np.linspace(0, 1, 3)

In [6]: xstep[:, None] + 1j*ystep
Out[6]: 
array([[0.+0.j , 0.+0.5j, 0.+1.j ],
       [1.+0.j , 1.+0.5j, 1.+1.j ]])

xstep[:, None] is equivalent to xstep[:, np.newaxis] and its purpose is to add a new axis to xstep on the right. Thus, xstep[:, None] is a 2D array of shape (2, 1).

In [19]: xstep[:, None].shape
Out[19]: (2, 1)

xstep[:, None] + 1j*ystep is thus the sum of a 2D array of shape (2, 1) and a 1D array of shape (3,).

NumPy broadcasting resolves this apparent shape conflict by automatically adding new axes (of length 1) on the left. So, by NumPy broadcasting rules, 1j*ystep is promoted to an array of shape (1, 3). (Notice that xstep[:, None] is required to explicitly add new axes on the right, but broadcasting will automatically add axes on the left. This is why 1j*ystep[None, :] was unnecessary though valid.)

Broadcasting further promotes both arrays to the common shape (2, 3) (but in a memory-efficient way, without copying the data). The values along the axes of length 1 are broadcasted repeatedly:

In [15]: X, Y = np.broadcast_arrays(xstep[:, None], 1j*ystep)

In [16]: X
Out[16]: 
array([[0., 0., 0.],
       [1., 1., 1.]])

In [17]: Y
Out[17]: 
array([[0.+0.j , 0.+0.5j, 0.+1.j ],
       [0.+0.j , 0.+0.5j, 0.+1.j ]])
2 of 3
3

You can use np.ogrid with imaginary "step" to obtain linspace semantics:

y, x = np.ogrid[0:1:2j, 0:1:3j]                                                                               
y + 1j*x
# array([[0.+0.j , 0.+0.5j, 0.+1.j ],                                                                                 
#        [1.+0.j , 1.+0.5j, 1.+1.j ]])                                                                                

Here the ogrid line means make an open 2D grid. axis 0: 0 to 1, 2 steps, axis 1: 0 to 1, 3 steps. The type of the slice "step" acts as a switch, if it is imaginary (in fact anything of complex type) its absolute value is taken and the expression is treated like a linspace. Otherwise range semantics apply.

The return values

y, x
# (array([[0.],                                                                                                       
#         [1.]]), array([[0. , 0.5, 1. ]]))                                                                                                                                                                                          

are "broadcast ready", so in the example we can simply add them and obtain a full 2D grid.

If we allow ourselves an imaginary "stop" parameter in the second slice (which only works with linspace semantics, so depending on your style you may prefer to avoid it) this can be condensed to one line:

sum(np.ogrid[0:1:2j, 0:1j:3j])
# array([[0.+0.j , 0.+0.5j, 0.+1.j ],
#        [1.+0.j , 1.+0.5j, 1.+1.j ]])

A similar but potentially more performant method would be preallocation and then broadcasting:

out = np.empty((y.size, x.size), complex)
out.real[...], out.imag[...] = y, x
out
# array([[0.+0.j , 0.+0.5j, 0.+1.j ],
#        [1.+0.j , 1.+0.5j, 1.+1.j ]])

And another one using outer sum:

np.add.outer(np.linspace(0,1,2), np.linspace(0,1j,3))
# array([[0.+0.j , 0.+0.5j, 0.+1.j ],
#        [1.+0.j , 1.+0.5j, 1.+1.j ]])
🌐
CodingNomads
codingnomads.com › arrays-in-numpy-ndarray
Arrays in NumPy: ndarray, np.empty, np.arange, np.linspace
... The syntax is (start, stop, num) where start is the first number in the sequence, stop is the last number in the sequence, and num is the number of numbers in the sequence. Note that stop is included in the sequence.