(Fixed) TypeError: FigureBase.gca() got an unexpected keyword argument ‘projection’ : Chris
by: Chris
blow post content copied from Be on the Right Side of Change
click here to view original post
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()
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!
July 23, 2023 at 12:31AM
Click here for more details...
=============================
The original post is available in Be on the Right Side of Change by Chris
this post has been published as it is through automation. Automation script brings all the top bloggers post under a single umbrella.
The purpose of this blog, Follow the top Salesforce bloggers and collect all blogs in a single place through automation.
============================

Post a Comment