在 Python 3 中绘制旋转实体(可能是 matplotlib)
Ploting solid of revolution in Python 3 (matplotlib maybe)
问候问题:
R 是 xy 平面中由抛物线 y=x^2+1 和线 y=x+3 界定的区域。通过绕 x 轴旋转 R 形成旋转体。我需要在 2D 和 solid revolution 3D 中绘制抛物线和直线,怎么做?
我安装了anaconda。
您可以使用 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()
要使用 plot_surface
绘制曲面,您首先要确定两个一维参数,u
和 v
:
u = np.linspace(-1, 2, 60)
v = np.linspace(0, 2*np.pi, 60)
使得 x
、y
、z
是参数 u
和 v
:
的函数
x = x(u, v)
y = y(u, v)
z = z(u, v)
关于 ax.plot_surface
需要注意的是它的前三个参数
必须是二维数组。所以我们使用 np.meshgrid
从坐标向量(u
和 v
)创建坐标矩阵(U
和 V
),并定义二维数组 X
, Y
, Z
是 U
和 V
:
的函数
X = U
Y1 = (U**2 + 1)*np.cos(V)
Z1 = (U**2 + 1)*np.sin(V)
对于坐标矩阵U
和V
上的每个位置,X
和Y
和Z
都有对应的值。这将创建一个从 2 维 uv
-space 到 3 维 xyz
-space 的映射。对于 uv
-space 中的每个矩形,我们在 xyz
-space 中的表面上都有一张脸。 plot_surface
画出的曲面就是由这些平面构成的
借助上面的内容,您可以使用小部件或 gif 使这些动态化。
制作gif:使用gif包:
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')
进行交互:使用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))
问候问题:
R 是 xy 平面中由抛物线 y=x^2+1 和线 y=x+3 界定的区域。通过绕 x 轴旋转 R 形成旋转体。我需要在 2D 和 solid revolution 3D 中绘制抛物线和直线,怎么做? 我安装了anaconda。
您可以使用 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()
要使用 plot_surface
绘制曲面,您首先要确定两个一维参数,u
和 v
:
u = np.linspace(-1, 2, 60)
v = np.linspace(0, 2*np.pi, 60)
使得 x
、y
、z
是参数 u
和 v
:
x = x(u, v)
y = y(u, v)
z = z(u, v)
关于 ax.plot_surface
需要注意的是它的前三个参数
必须是二维数组。所以我们使用 np.meshgrid
从坐标向量(u
和 v
)创建坐标矩阵(U
和 V
),并定义二维数组 X
, Y
, Z
是 U
和 V
:
X = U
Y1 = (U**2 + 1)*np.cos(V)
Z1 = (U**2 + 1)*np.sin(V)
对于坐标矩阵U
和V
上的每个位置,X
和Y
和Z
都有对应的值。这将创建一个从 2 维 uv
-space 到 3 维 xyz
-space 的映射。对于 uv
-space 中的每个矩形,我们在 xyz
-space 中的表面上都有一张脸。 plot_surface
画出的曲面就是由这些平面构成的
借助上面的内容,您可以使用小部件或 gif 使这些动态化。
制作gif:使用gif包:
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')
进行交互:使用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))