Skip to content

Parametric Curves and Surfaces

Parametric Curves

ax = plt.figure(figsize=(8,6)).add_subplot(projection='3d')

# Prepare arrays x, y, z
theta = np.linspace(-4 * np.pi, 4 * np.pi, 100)
x = np.cos(theta)
y = np.sin(theta)
z = 3*x**2 + 5*y**2

# quiver: x,y,z,dx,dy,dz
ax.quiver(1,0,3,0,1,0,pivot='tail', color = 'tab:orange',
    arrow_length_ratio=0.1,label='tangent vectors')  
# prepare point/vector for tangent at t=pi/3
t1=np.pi/3
x1 = np.cos(t1)
y1 = np.sin(t1)
z1 = 3*x1**2+5*y1**2
dx1 = -np.sin(t1)
dy1 = np.cos(t1)
dz1 = 4*x1*y1
ax.quiver(x1,y1,z1,dx1,dy1,dz1,pivot='tail',color='tab:orange',
    arrow_length_ratio=0.1)

ax.plot(x, y, z, label='parametric curve')
ax.set_zlim([3, 7])
ax.set_xticks([-1+0.5*XX for XX in range(5)])
ax.set_yticks([-1+0.5*XX for XX in range(5)])
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z')
ax.legend()

Graph Graph

Parametric Surfaces

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# Generate surface mesh
u = np.linspace(0,1,200)
v = np.linspace(0,2*np.pi,200)
U,V = np.meshgrid(u,v)
Y = U*np.sin(V)
X = U*np.cos(V)
Z = U*np.cos(V)**2 - U*np.sin(V)**2

# Display the plot
fig = plt.figure(figsize=(12,8))
ax = fig.add_subplot(projection='3d')
ax.plot_surface(X,Y,Z,rstride=4, cstride=4, linewidth=0, alpha=0.7)

cset = ax.contour(X, Y, Z, zdir='z', offset=-1, cmap=matplotlib.cm.coolwarm)

ax.set_xlim3d(-1, 1);
ax.set_ylim3d(-1, 1);
ax.set_zlim3d(-1, 1);

Graph Graph

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

# Generate torus mesh
angle = np.linspace(0, 2 * np.pi, 32)
theta, phi = np.meshgrid(angle, angle)
r, R = .25, 1.
X = (R + r * np.cos(phi)) * np.cos(theta)
Y = (R + r * np.cos(phi)) * np.sin(theta)
Z = r * np.sin(phi)

# Display the mesh
fig = plt.figure(figsize=(8,6))
ax = fig.gca(projection = '3d')
ax.set_xlim3d(-1, 1)
ax.set_ylim3d(-1, 1)
ax.set_zlim3d(-1, 1)
ax.plot_surface(X, Y, Z, color = 'w', rstride = 1, cstride = 1)

Graph Graph

Viewing Angle

Sometimes the default viewing angle isn't the best view of your plot, so changing the viewing angle is desirable. This can be done with view_init(elev='', azim=''). Creating a number of images with different viewing angles and then selecting the best one is a good way to do this. Stitching the images into an animated gif could also be done to create a nice movie.

# Generate surface mesh
u = np.linspace(0,1,200)
v = np.linspace(0,2*np.pi,200)
U,V = np.meshgrid(u,v)
Y = U*np.sin(V)
X = U*np.cos(V)
Z = U*np.cos(V)**2 - U*np.sin(V)**2

# Display the plot
fig = plt.figure(figsize=(12,8))
ax = fig.add_subplot(projection='3d')
ax.plot_surface(X,Y,Z,rstride=4, cstride=4, linewidth=0, alpha=0.7)

cset = ax.contour(X, Y, Z, zdir='z', offset=-1, cmap=matplotlib.cm.coolwarm)

ax.set_xlim3d(-1, 1);
ax.set_ylim3d(-1, 1);
ax.set_zlim3d(-1, 1);

# Create images from different viewing angles
for ii in range(0,180,30):
    ax.view_init(elev=20., azim=ii)
    fig.savefig("movie%d.png" % ii)