Python:如何绕z轴旋转曲面并制作3d图?

时间:2016-02-24 02:39:29

标签: python matplotlib plotly

我想获得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图应该如下所示:
enter image description here

2 个答案:

答案 0 :(得分:2)

好的,所以我认为你真的要求围绕轴旋转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)
获取圆圈周围点的Trig方式是:
x = r * cos(theta)
y = r * sin(theta)

因为你r是你的rho,theta是revolve_steps

通过使用np.dot进行矩阵乘法,你得到一个2d数组,其中x' s和y' s的行将对应于z' s

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

找到解决方案

答案 1 :(得分:0)

仅旋转轴,在这种情况下为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()

结果:

Solid from red curve