To illustrate an optimization problem, I want all of this in the same 3D plot:
This is my code so far:
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import LinearLocator
import numpy as np
from mpl_toolkits import mplot3d
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
X = np.linspace(-5,5,100)
Y = X
X, Y = np.meshgrid(X, Y)
Z = 50 - X**2 - Y**2
#Plotting curve on the surface
ax = plt.axes(projection='3d')
yline = np.linspace(-5,5,100)
xline = -np.sqrt(4/(2+yline**2)) #the x-values of the curve in the xy-plane
zline = 50 - xline**2 - yline**2
ax.plot3D(xline, yline, zline, "black")
surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm)
ax.set_zlim(0, 50)
#Plotting curve in xy-plane
a = 5
g = 1 - 2*X - X*Y**2
plt.contour(X,Y,g, [a], offset=0)
plt.show()
Here is the plot from two different angles:
Some problems:
These questions might be dummy questions, but answers and tips are highly appreciated!
The code creates two axes objects (both assigned to the ax
variable) in the same figure. This is not needed and results in double ticks marks.
To make the path on the surface more visible, plot it with a higher zorder.
The curve on the surface does not overlap with the curve on the xy plane because these are different curves. To plot the projection of the surface curve on the xy plane, set all z-coordinates of the curve to 0.
Below is the code with these changes.
import matplotlib.pyplot as plt
from matplotlib import cm
from matplotlib.ticker import LinearLocator
import numpy as np
from mpl_toolkits import mplot3d
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
X = np.linspace(-5, 5, 100)
Y = X
X, Y = np.meshgrid(X, Y)
Z = 50 - X**2 - Y**2
yline = np.linspace(-5, 5, 100)
xline = -np.sqrt(4 / (2 + yline**2))
zline = 50 - xline**2 - yline**2
ax.plot3D(xline, yline, zline, "b", zorder=10)
surf = ax.plot_surface(X, Y, Z, cmap=cm.coolwarm, alpha=0.7)
ax.set_zlim(0, 50)
#Plotting curve in xy-plane
ax.plot3D(xline, yline, 0, "k")
plt.show()