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

(Fixed) TypeError: FigureBase.gca() got an unexpected keyword argument ‘projection’
by: Chris
blow post content copied from  Be on the Right Side of Change
click here to view original post


4/5 - (1 vote)

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.
============================

Salesforce