(Fixed) TypeError: FigureBase.gca() got an unexpected keyword argument ‘projection’

When trying to plot a 3D normal distribution recently, I encountered the following error:

TypeError                                 Traceback (most recent call last)

<ipython-input-10-ee1b0cd4b744> in <cell line: 32>()
     30 fig = plt.figure()
     31 
---> 32 ax = fig.gca(projection='3d')
     33 
     34 # create a 3D surface plot of the multivariate normal distribution

πŸ‘‰ TypeError: FigureBase.gca() got an unexpected keyword argument 'projection' πŸ€”

<Figure size 640x480 with 0 Axes>

This happened after running the following code snippet — see the highlighted line:

ax = fig.gca(projection='3d')

Here’s the full context in case you want to reproduce the error: πŸ‘‡

# import necessary libraries
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import multivariate_normal
from mpl_toolkits.mplot3d import Axes3D

# define parameters for x and y distributions
mu_x = 0  # mean of x
variance_x = 3  # variance of x

mu_y = 0  # mean of y
variance_y = 15  # variance of y

# define a grid for x and y values
x = np.linspace(-10, 10, 500)  # generate 500 points between -10 and 10 for x
y = np.linspace(-10, 10, 500)  # generate 500 points between -10 and 10 for y
X, Y = np.meshgrid(x, y)  # create a grid for (x,y) pairs

# create an empty array of the same shape as X to hold the (x, y) coordinates
pos = np.empty(X.shape + (2,))

# fill the pos array with the x and y coordinates
pos[:, :, 0] = X  
pos[:, :, 1] = Y  

# create a multivariate normal distribution using the defined parameters
rv = multivariate_normal([mu_x, mu_y], [[variance_x, 0], [0, variance_y]])

# create a new figure for 3D plot
fig = plt.figure()

ax = fig.gca(projection='3d')

# create a 3D surface plot of the multivariate normal distribution
ax.plot_surface(X, Y, rv.pdf(pos), cmap='viridis', linewidth=0)

# set labels for the axes
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')

# display the 3D plot
plt.show()

I experienced this error when creating the code as explained in my other blog article on creating a 3D normal distribution plot in Python.

But now let’s dive into the solution: πŸ‘‡

Solution

The simple solution is to replace the line:

ax = fig.gca(projection='3d')

with the line

ax = fig.add_subplot(projection='3d')

And voila, it’ll work!

This error appears because, in Matplotlib 3.4 and later versions, the function gca() no longer takes keyword arguments. However, many code snippets on the web still have the same old and stale recommendations.

Here’s the updated code snippet with the line swapped, i.e., I replaced fig.gca(projection='3d') with fig.add_subplot(projection='3d').

# import necessary libraries
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import multivariate_normal
from mpl_toolkits.mplot3d import Axes3D

# define parameters for x and y distributions
mu_x = 0  # mean of x
variance_x = 3  # variance of x

mu_y = 0  # mean of y
variance_y = 15  # variance of y

# define a grid for x and y values
x = np.linspace(-10, 10, 500)  # generate 500 points between -10 and 10 for x
y = np.linspace(-10, 10, 500)  # generate 500 points between -10 and 10 for y
X, Y = np.meshgrid(x, y)  # create a grid for (x,y) pairs

# create an empty array of the same shape as X to hold the (x, y) coordinates
pos = np.empty(X.shape + (2,))

# fill the pos array with the x and y coordinates
pos[:, :, 0] = X  
pos[:, :, 1] = Y  

# create a multivariate normal distribution using the defined parameters
rv = multivariate_normal([mu_x, mu_y], [[variance_x, 0], [0, variance_y]])

# create a new figure for 3D plot
fig = plt.figure()

# add a 3D subplot to the figure
ax = fig.add_subplot(projection='3d')

# create a 3D surface plot of the multivariate normal distribution
ax.plot_surface(X, Y, rv.pdf(pos), cmap='viridis', linewidth=0)

# set labels for the axes
ax.set_xlabel('X axis')
ax.set_ylabel('Y axis')
ax.set_zlabel('Z axis')

# display the 3D plot
plt.show()

The beautiful result when it works πŸ₯³ πŸ‘‡

I’d love to see you on my email list — join 150k coders that learn and improve their skills together. We also have cheat sheets:

Come join us! πŸ€—