Numpy Meshgrid, Explained

This tutorial will show you how to use Numpy meshgrid.

It will explain what the meshgrid function does, explain the syntax, and show you clear examples to help develop your intuition for how this technique works.

If you need something specific, you can click on any of the following links.

Table of Contents:

Having said that, Numpy meshgrid is fairly complicated to understand, and I recommend that you read this tutorial from start to finish.

A quick introduction to Numpy Meshgrid

Numpy meshgrid is a tool for numeric data manipulation in Python.

We use Numpy meshgrid to create a rectangular grid of x and y values.

More specifically, meshgrid creates coordinate values that enable us to construct a rectangular grid of values.

It does this in a somewhat roundabout way.

As inputs to the function, we provide 1-dimensional arrays with numeric values. These numeric values will be the coordinates of the new “meshgrid.”

The output of np.meshgrid is a set of Numpy arrays that contain the coordinates of this new grid space.

A simple example that shows and explains how Numpy meshgrid inputs 1D arrays of coordinates, and outputs Numpy arrays with values that serve as coordinates for a grid-like Euclidean space.

It’s a complicated way to create coordinates at every point in a grid-like space; a “meshgrid,” if you will.

This this function often confuses beginners, and I think that the best way to understand it is with examples. I’m going to show you some examples below, but first, let’s look at the syntax.

The Syntax of Numpy Meshgrid

Now that you’ve learned what Numpy meshgrid does at a high level, let’s get into the details and look at the syntax.

A quick note

Before I move on, one quick note:

Remember that when we import Numpy, we almost always import it with the alias, np, which allows us to call Numpy functions with the suffix np.

import numpy as np

That’s the common convention among Python data scientists, and going forward, I’ll assume that you’ve imported Numpy this way.

np.meshgrid syntax

The syntax is somewhat simple.

You call the function as np.meshgrid().

Inside the parenthesis, the first arguments should be 1D Numpy arrays (or array like objects) that contain the values you want to use as grid coordinates.

An image that explains the syntax of Numpy meshgrid.

There are also some optional parameters like the sparse parameter that we’ll discuss in a moment.

The arguments and parameters of np.meshgrid

Let’s look at the inputs and optional parameters of np.meshgrid.

  • x1, x2, ... xn
  • sparse
  • indexing
x1, x2, ... xn (required)

These are the input arrays to the function.

These should be 1-dimensional Numpy arrays with numeric values, although they can also be array-like objects, such as Python lists.

Most commonly, we use two input arrays. This will cause Numpy meshgrid to create a 2D grid space.

However, it’s technically possible to have only one input array, for a 1D “grid.”

It’s also possible to provide three or more input arrays, which will create the values for a higher-dimensional grid space.

sparse

The sparse parameter enables you to specify if you want the function to strictly create values for the axes (like axis tick mark values), or if you want it to create full grids of coordinate values.

If you set sparse = True, it will only create values for the axes of the new space.

If you set sparse = False, it will create coordinates for every new point in the created grid space. The setting sparse = False is the default.

Confused?

You should look at example 1 to see what happens when we set sparse = True. I think that example will clarify what this does.

indexing

The indexing parameter controls how the outputs are indexed.

  • indexing = 'xy' creates output with Cartesian indexing
  • indexing = 'ij' creates output with matrix indexing

'xy' is the default.

Examples of How to use Numpy Meshgrid

Now that we’ve looked at the syntax, let’s look at some example of Numpy meshgrid.

Examples:

Run this code first

One quick note before we run the examples.

All of these examples assume that you’ve imported Numpy.

The common convention is to import Numpy with the alias “np.”

You can do that like this:

import numpy as np

Once you run that code, you’ll be read to run the examples.

EXAMPLE 1: Numpy meshgrid with “sparse = True”

Here, instead of starting with the simplest example that removes any optional parameters, we’re going to start with an example that actually uses one of the optional parameters.

Specifically, we’re going to use the sparse parameter, and set sparse = True.

Let’s run it and look at the output, and then I’ll explain why this is useful.

np.meshgrid([1,2,3], [5,6,7], sparse = True)

OUT:

[array([[1, 2, 3]]),
 array([[5],
        [6],
        [7]])]
Explanation

Take a look at the inputs and then look at the outputs.

The inputs are two 1-dimensional Python lists: [1,2,3] and [5,6,7]. Here, I used lists instead of Numpy arrays, to make the code easier to read, but we could have also used 1D Numpy arrays, just the same.

So the inputs are 1D Python lists.

But the outputs are 2D Numpy arrays.

And most importantly look at how they are structured.

The first array, [[1, 2, 3]], has been kept horizontal.

But the second array is structured vertically:

[[5],
[6],
[7]]

Why?

You need to think of these outputs like x-axis values and y-axis values.

Numpy meshgrid is creating outputs that we could use for a Euclidean, x/y grid.

So we’re providing the input values, and it’s producing outputs that can act like x and y axis values.

An example of Numpy meshgrid, with sparse = True.

Importantly, when we set sparse = True, np.meshgrid only produces outputs that act like the axis-values of a coordinate system.

As you’ll see in the upcoming examples, if set sparse = False, then np.meshgrid will produce values for all points in the new grid coordinate system.

(Note that everything I said above applies to the 2D case, and will be more complicated with for n-dimensional inputs.)

EXAMPLE 2: Numpy meshgrid with two inputs and two 2D output arrays

Next, we’ll look at a very simple example without any additional parameters.

So here, we’ll use Numpy meshgrid with two Python lists as inputs.

And we’ll remove the sparse parameter that we saw in example 1.

Let’s take a look:

np.meshgrid([1,2,3], [5,6,7])

And here is the output:

[array([[1, 2, 3],
        [1, 2, 3],
        [1, 2, 3]]),
 array([[5, 5, 5],
        [6, 6, 6],
        [7, 7, 7]])]
Explanation

You’ll notice that the code is fairly simple, but the output is somewhat more complex than the output we saw in example 1.

In example 1, we set sparse = True, but here we’ve removed the sparse parameter, so it’s being set to the default of sparse = False.

An example of Numpy meshgrid with two 1D inputs, and two 2D outputs.

Here, I’ve color-coded the outputs, just to help you see how they are structured.

Notice the relationship between the input and the output.

In this example, there are two 2-dimensional output arrays.

The first output array contains the values from the first input: 1,2,3. But these values have been repeated downward.

The second output array contains the values from the second input: 5,6,7. But these values have been repeated across.

Meshgrid is creating coordinates for a grid of values

You might be asking, what exactly are these two output arrays for?

Numpy meshgrid is providing us with coordinates.

As I suggested previously, meshgrid is creating coordinates that would allow us to create a Euclidean, x and y space. (At least, that’s the case in this example. It’s giving us coordinates for a 2D space. If we used higher-dimensional inputs, it might give us coordinates for a higher-dimensional space. But that’s a lot more complicated, so forget that right now.)

What does this look like?

Think of a set of coordinates in a grid-like Euclidean space, defined by the values in the input arrays:

Explanation of how Numpy meshgrid creates Numpy arrays, which in turn act as coordinate values for a Euclidean grid.

That’s it guys.

That’s what meshgrid does.

It’s a complicated, ass-backwards, hard-to-understand method of creating coordinates for a grid system.

EXAMPLE 3: A “real world” machine learning example that shows how we use Numpy meshgrid

Ok.

Let’s finally do a “real world” example where we actually use Numpy meshgrid for something useful.

Here, we’re going to use Numpy meshgrid to visualize the decision boundary of a machine learning model.

I’ll admit: this is a complicated example, and there’s a lot going on here. If you’re confused by this, you should consider enrolling in our Numpy course or our Python machine learning course.

Code

Ok, we’ll start by importing our packages.

# IMPORT PACKAGES
import numpy as np

import plotly.graph_objects as go
import seaborn as sns

from sklearn.datasets import make_moons
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier

Next, we need to create a dataset and split it.

Here, we’re going to use scikit learn make_moons to create moon-shaped data.

# LOAD DATA
X, y =  make_moons(n_samples = 200
                   ,noise = .1
                   ,random_state = 3
                   )

X.shape
y.shape

Here, we’ll visualize it with the Seaborn scatterplot function:

# PLOT DATA
plt.style.use('fivethirtyeight')
sns.scatterplot(x = X[:,0], y = X[:,1], hue = y)

OUT:

A scatterplot of moon-shaped categorical data, made with the sns.scatterplot function.

Now we’ll split the data with the Sklearn train_test_split function.

#-------------------------
# CREATE TRAIN & TEST DATA
#-------------------------

(X_train, X_test, y_train, y_test) = train_test_split(X
                                                      ,y
                                                      ,test_size = .2
                                                      )

Ok. Here’s the part where we use meshgrid.

We’re going to create a grid of x/y coordinates with Numpy meshgrid.

To to this, you’ll note that I’m setting a grid_unit_size, which is the size of the steps in the grid.

I’m also setting the boundaries of the grid space with x_min, y_min, etc.

Notice also that I’m using the Numpy arange function to create the x-range and y-range for the data. These serve as inputs to meshgrid.

# CREATE MESHGRID ON WHICH WE WILL RUN OUR MODEL

grid_unit_size = .02
margin = 0.25

x_min = X[:, 0].min() - margin
x_max = X[:, 0].max() + margin
y_min = X[:, 1].min() - margin
y_max = X[:, 1].max() + margin

x_range = np.arange(start = x_min, stop = x_max, step = grid_unit_size )
y_range = np.arange(start = y_min, stop = y_max, step = grid_unit_size )

x_gridvalues, y_gridvalues = np.meshgrid(x_range, y_range)

Next, we’ll create a KNN classifier model.

# INITIALIZE CLASSIFIER AND FIT MODEL
knn_classifier = KNeighborsClassifier(15, weights='uniform')
knn_classifier.fit(X, y)

And now that we have our model, we’ll use it to compute values on our grid.

Notice that to do this, we need to do a fair amount of data wrangling with Numpy vstack and Numpy flatten.

# COMPUTE PROBABILITIES ON GRID
gridvalues_combined_tidy = np.vstack([x_gridvalues.flatten(), y_gridvalues.flatten()]).T
knn_class_probabilities = knn_classifier.predict_proba(gridvalues_combined_tidy)

probability_postive_class = knn_class_probabilities[:,1]

After doing this, we have the class probabilities for the positive class.

Finally, we can plot them using Plotly:

# PLOT THE PROBABILITIES ON THE MESHGRID
fig = go.Figure(data=[
    go.Contour(
        x = x_range
        ,y = y_range
        ,z = probability_postive_class.reshape(x_gridvalues.shape)
        ,colorscale = 'RdBu'
        #,alpha = .3
    )
])

fig.show()

A plot that shows the probabilities for a KNN classification model, computed on a meshgrid and visualized to show the data as a decision boundary.

I’ll admit: there’s a lot going on here. I’m sure that it’s a bit hard to understand if you’re a beginner.

But really, you just need to know the little functions and tools that we use to do all of this.

Numpy meshgrid is one, but to really understand this, you need to know a fair amount about Numpy, scikit learn, and data visualization in Python (Seaborn and/or Plotly).

Frequently asked questions about Numpy Meshgrid

Now that we’ve looked at how Numpy meshgrid works, and looked at some examples, let’s look at some frequently asked questions about the function.

Frequently asked questions:

Question 1: Why is Numpy Meshgrid so hard to understand?

I’m convinced that the guys who designed Python data scientists are sadists.

Half the tools for Python data science are much harder than they need to be.

(If you don’t believe me, try using R instead.)

Question 2: What does Numpy meshgrid do?

It creates arrays with numeric values, and the values function like coordinates for a grid-like space.

I recommend reviewing example 2 to really see what’s going on.

Question 3: Why are you so great at explaining complicated Python tools, Josh

Because I’m a gentleman and a scholar.

Leave your other questions in the comments below

Have other questions about meshgrid?

Did I forget something?

Leave your extra questions in the comments section at the bottom of the page.

For more Numpy tutorials, sign up for our email list

This tutorial should have helped you understand how to use Numpy meshgrid, but if you want to be great at data science and ML in Python, then there’s a lot more to learn.

If you’re ready to master data science and machine learning in Python, then sign up for our FREE email list.

When you sign up, you’ll get free tutorials on:

  • NumPy
  • Pandas
  • Base Python
  • Scikit learn
  • Machine learning
  • Deep learning
  • … and more.

Again, to sign up for this free email list, just enter your best email address here:

Joshua Ebner

Joshua Ebner is the founder, CEO, and Chief Data Scientist of Sharp Sight. Prior to founding the company, Josh worked as a Data Scientist at Apple. He has a degree in Physics from Cornell University.

1 thought on “Numpy Meshgrid, Explained”

  1. As always, fantastic way of explaining the complex topic. Is there any possibility to have the search facility available on the web site so that i can search it out for example np.ones_like, np.triu etc.

    Reply

Leave a Comment