Python: 如何围绕 z 轴旋转曲面并制作 3d 图?
Python: How to revolve a surface around z axis and make a 3d plot?
我想要如下所示的 2d 和 3d 图。
给出曲线的方程
我们如何在 python 中做到这一点?
我知道可能有重复但在发布时
我找不到任何有用的帖子。
我最初的尝试是这样的:
# Imports
import numpy as np
import matplotlib.pyplot as plt
# to plot the surface rho = b*cosh(z/b) with rho^2 = r^2 + b^2
z = np.arange(-3, 3, 0.01)
rho = np.cosh(z) # take constant b = 1
plt.plot(rho,z)
plt.show()
部分相关链接如下:
Rotate around z-axis only in plotly
3d 图应如下所示:
好的,所以我认为您实际上是在要求围绕轴旋转 2d 曲线以创建曲面。我来自 CAD 背景,所以这就是我解释事情的方式。
而且我不是最擅长数学的人,所以请原谅任何笨拙的术语。不幸的是,您必须完成其余的数学运算才能获得网格的所有点。
这是您的代码:
#import for 3d
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
将 arange 更改为捕获端点的 linspace,否则 arange 将缺少数组末尾的 3.0:
z = np.linspace(-3, 3, 600)
rho = np.cosh(z) # take constant b = 1
因为 rho 是每个 z 高度的半径,我们需要计算该半径周围的 x,y 点。在此之前,我们必须弄清楚在该半径上的什么位置才能获得 x,y 坐标:
#steps around circle from 0 to 2*pi(360degrees)
#reshape at the end is to be able to use np.dot properly
revolve_steps = np.linspace(0, np.pi*2, 600).reshape(1,600)
三角函数绕圆取点的方法是:
x = r*cos(θ)
y = r*sin(θ)
对你来说,r 是你的 rho,theta 是 revolve_steps
通过使用 np.dot 进行矩阵乘法,您将得到一个二维数组,其中 x 和 y 的行将对应于 z 的
theta = revolve_steps
#convert rho to a column vector
rho_column = rho.reshape(600,1)
x = rho_column.dot(np.cos(theta))
y = rho_column.dot(np.sin(theta))
# expand z into a 2d array that matches dimensions of x and y arrays..
# i used np.meshgrid
zs, rs = np.meshgrid(z, rho)
#plotting
fig, ax = plt.subplots(subplot_kw=dict(projection='3d'))
fig.tight_layout(pad = 0.0)
#transpose zs or you get a helix not a revolve.
# you could add rstride = int or cstride = int kwargs to control the mesh density
ax.plot_surface(x, y, zs.T, color = 'white', shade = False)
#view orientation
ax.elev = 30 #30 degrees for a typical isometric view
ax.azim = 30
#turn off the axes to closely mimic picture in original question
ax.set_axis_off()
plt.show()
#ps 600x600x600 pts takes a bit of time to render
我不确定它是否已在最新版本的 matplotlib 中修复,但设置 3d 图的纵横比为:
ax.set_aspect('equal')
效果不是很好。您可以在 this stack overflow question
找到解决方案
只旋转轴,在本例中为x
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d as axes3d
np.seterr(divide='ignore', invalid='ignore')
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x = np.linspace(-3, 3, 60)
rho = np.cosh(x)
v = np.linspace(0, 2*np.pi, 60)
X, V = np.meshgrid(x, v)
Y = np.cosh(X) * np.cos(V)
Z = np.cosh(X) * np.sin(V)
ax.set_xlabel('eje X')
ax.set_ylabel('eje Y')
ax.set_zlabel('eje Z')
ax.plot_surface(X, Y, Z, cmap='YlGnBu_r')
plt.plot(x, rho, 'or') #Muestra la curva que se va a rotar
plt.show()
结果:
我想要如下所示的 2d 和 3d 图。
给出曲线的方程
我们如何在 python 中做到这一点?
我知道可能有重复但在发布时
我找不到任何有用的帖子。
我最初的尝试是这样的:
# Imports
import numpy as np
import matplotlib.pyplot as plt
# to plot the surface rho = b*cosh(z/b) with rho^2 = r^2 + b^2
z = np.arange(-3, 3, 0.01)
rho = np.cosh(z) # take constant b = 1
plt.plot(rho,z)
plt.show()
部分相关链接如下:
Rotate around z-axis only in plotly
3d 图应如下所示:
好的,所以我认为您实际上是在要求围绕轴旋转 2d 曲线以创建曲面。我来自 CAD 背景,所以这就是我解释事情的方式。 而且我不是最擅长数学的人,所以请原谅任何笨拙的术语。不幸的是,您必须完成其余的数学运算才能获得网格的所有点。
这是您的代码:
#import for 3d
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
将 arange 更改为捕获端点的 linspace,否则 arange 将缺少数组末尾的 3.0:
z = np.linspace(-3, 3, 600)
rho = np.cosh(z) # take constant b = 1
因为 rho 是每个 z 高度的半径,我们需要计算该半径周围的 x,y 点。在此之前,我们必须弄清楚在该半径上的什么位置才能获得 x,y 坐标:
#steps around circle from 0 to 2*pi(360degrees)
#reshape at the end is to be able to use np.dot properly
revolve_steps = np.linspace(0, np.pi*2, 600).reshape(1,600)
三角函数绕圆取点的方法是:
x = r*cos(θ)
y = r*sin(θ)
对你来说,r 是你的 rho,theta 是 revolve_steps
通过使用 np.dot 进行矩阵乘法,您将得到一个二维数组,其中 x 和 y 的行将对应于 z 的
theta = revolve_steps
#convert rho to a column vector
rho_column = rho.reshape(600,1)
x = rho_column.dot(np.cos(theta))
y = rho_column.dot(np.sin(theta))
# expand z into a 2d array that matches dimensions of x and y arrays..
# i used np.meshgrid
zs, rs = np.meshgrid(z, rho)
#plotting
fig, ax = plt.subplots(subplot_kw=dict(projection='3d'))
fig.tight_layout(pad = 0.0)
#transpose zs or you get a helix not a revolve.
# you could add rstride = int or cstride = int kwargs to control the mesh density
ax.plot_surface(x, y, zs.T, color = 'white', shade = False)
#view orientation
ax.elev = 30 #30 degrees for a typical isometric view
ax.azim = 30
#turn off the axes to closely mimic picture in original question
ax.set_axis_off()
plt.show()
#ps 600x600x600 pts takes a bit of time to render
我不确定它是否已在最新版本的 matplotlib 中修复,但设置 3d 图的纵横比为:
ax.set_aspect('equal')
效果不是很好。您可以在 this stack overflow question
找到解决方案只旋转轴,在本例中为x
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d as axes3d
np.seterr(divide='ignore', invalid='ignore')
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x = np.linspace(-3, 3, 60)
rho = np.cosh(x)
v = np.linspace(0, 2*np.pi, 60)
X, V = np.meshgrid(x, v)
Y = np.cosh(X) * np.cos(V)
Z = np.cosh(X) * np.sin(V)
ax.set_xlabel('eje X')
ax.set_ylabel('eje Y')
ax.set_zlabel('eje Z')
ax.plot_surface(X, Y, Z, cmap='YlGnBu_r')
plt.plot(x, rho, 'or') #Muestra la curva que se va a rotar
plt.show()
结果: