Greetings the problem:
R is a region in the xy plane bounded by the parabola y=x^2+1 and line y=x+3. A solid of revolution is formed by rotating R around the x axi
Piggybacking on above, you can make these dynamic with widgets or gifs.
Make a gif: Use the gif package:
import gif
@gif.frame
def plot_volume(angle):
fig = plt.figure(figsize = (20, 15))
ax2 = fig.add_subplot(1, 1, 1, projection = '3d')
angles = np.linspace(0, 360, 20)
x = np.linspace(-1, 2, 60)
v = np.linspace(0, 2*angle, 60)
U, V = np.meshgrid(x, v)
Y1 = (U**2 + 1)*np.cos(V)
Z1 = (U**2 + 1)*np.sin(V)
Y2 = (U + 3)*np.cos(V)
Z2 = (U + 3)*np.sin(V)
X = U
ax2.plot_surface(X, Y1, Z1, alpha = 0.2, color = 'blue', rstride = 6, cstride = 6)
ax2.plot_surface(X, Y2, Z2, alpha = 0.2, color = 'red', rstride = 6, cstride = 6)
ax2.set_xlim(-3,3)
ax2.set_ylim(-5,5)
ax2.set_zlim(-5,5)
ax2.view_init(elev = 50, azim = 30*angle)
ax2.plot_wireframe(X, Y2, Z2)
ax2.plot_wireframe(X, Y1, Z1, color = 'black')
ax2._axis3don = False
frames = []
for i in np.linspace(0, 2*np.pi, 20):
frame = plot_volume(i)
frames.append(frame)
gif.save(frames, 'images/vol1.gif', duration = 500)
from IPython.display import Image
Image('images/vol1.gif')
Make Interactive: Use ipywidgets.
def three_d_plotter(angle, rotate, turn):
fig = plt.figure(figsize = (13, 6))
ax = fig.add_subplot(1, 1, 1, projection='3d')
u = np.linspace(-1, 2, 60)
v = np.linspace(0, angle, 60)
U, V = np.meshgrid(u, v)
X = U
Y1 = (U**2 + 1)*np.cos(V)
Z1 = (U**2 + 1)*np.sin(V)
Y2 = (U + 3)*np.cos(V)
Z2 = (U + 3)*np.sin(V)
ax.plot_surface(X, Y1, Z1, alpha=0.3, color='red', rstride=6, cstride=12)
ax.plot_surface(X, Y2, Z2, alpha=0.3, color='blue', rstride=6, cstride=12)
ax.plot_wireframe(X, Y2, Z2, alpha=0.3, color='blue', rstride=6, cstride=12)
ax._axis3don = False
ax.view_init(elev = rotate, azim = turn)
plt.show()
from ipywidgets import interact
import ipywidgets as widgets
interact(three_d_plotter, angle = widgets.FloatSlider(0, min = 0, max = 2*np.pi, step = np.pi/10),
rotate = widgets.FloatSlider(0, min = 0, max = 360, step = 5),
turn = widgets.FloatSlider(0, min = 0, max = 500, step = 5))
You could use plot_surface:
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d as axes3d
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection='3d')
u = np.linspace(-1, 2, 60)
v = np.linspace(0, 2*np.pi, 60)
U, V = np.meshgrid(u, v)
X = U
Y1 = (U**2 + 1)*np.cos(V)
Z1 = (U**2 + 1)*np.sin(V)
Y2 = (U + 3)*np.cos(V)
Z2 = (U + 3)*np.sin(V)
ax.plot_surface(X, Y1, Z1, alpha=0.3, color='red', rstride=6, cstride=12)
ax.plot_surface(X, Y2, Z2, alpha=0.3, color='blue', rstride=6, cstride=12)
plt.show()
To plot a surface using plot_surface you begin by identifying two 1-dimensional parameters, u and v:
u = np.linspace(-1, 2, 60)
v = np.linspace(0, 2*np.pi, 60)
such that x, y, z are functions of the parameters u and v:
x = x(u, v)
y = y(u, v)
z = z(u, v)
The thing to notice about ax.plot_surface is that its first three arguments
must be 2D arrays. So we use np.meshgrid to create coordinate matrices (U and V) out of coordinate vectors (u and v), and define 2D arrays X, Y, Z to be functions of U and V:
X = U
Y1 = (U**2 + 1)*np.cos(V)
Z1 = (U**2 + 1)*np.sin(V)
For each location on the coordinate matrices U and V, there is a corresponding value for X and Y and Z. This creates a map from 2-dimensional uv-space to 3-dimensional xyz-space. For every rectangle in uv-space there is a face on our surface in xyz-space. The curved surface drawn by plot_surface is composed of these flat faces.