如何使用matplotlib在python中绘制完美光滑的球体?

时间:2018-08-02 04:48:34

标签: python matplotlib plot graph surface

我正在尝试使用matplotlib在python中绘制一个完美光滑的球体。我一直在使用以下代码:

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

fig = plt.figure(1)    
ax = fig.add_subplot(111, projection='3d')

u = np.linspace(0, 2 * np.pi, 100)
v = np.linspace(0, np.pi, 100)
x = np.outer(np.cos(u), np.sin(v))
y = np.outer(np.sin(u), np.sin(v))
z = np.outer(np.ones(np.size(u)), np.cos(v))

ax.plot_surface(x, y, z, linewidth=0.0)

plt.show()

我获得的情节附在下面: figure

生成的图形由其上的矩形表面的小块组成。是否可以理顺边界或使其难以区分并形成完美光滑的球体?

1 个答案:

答案 0 :(得分:0)

Matplotlib通过将3d曲面分解为相同颜色的小子多边形来进行绘制,如documentation中所述,因此,您的结果并不出乎意料。为了获得更平滑的表面,您必须提供更多的数据点。但是,有一个小的变化,即plot_surface()可能不会使用您提供的所有数据。这由cstriderstride关键字控制。对默认值的计算方式对我来说还不是很清楚,但下面是一个演示效果的小例子:

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

fig,axes = plt.subplots(ncols=2,nrows=2,subplot_kw=dict(projection='3d'))

N=50
stride=2
ax = axes[0,0]
u = np.linspace(0, 2 * np.pi, N)
v = np.linspace(0, np.pi, N)
x = np.outer(np.cos(u), np.sin(v))
y = np.outer(np.sin(u), np.sin(v))
z = np.outer(np.ones(np.size(u)), np.cos(v))
ax.plot_surface(x, y, z, linewidth=0.0, cstride=stride, rstride=stride)
ax.set_title('{0}x{0} data points, stride={1}'.format(N,stride))

N=50
stride=1
ax = axes[0,1]
u = np.linspace(0, 2 * np.pi, N)
v = np.linspace(0, np.pi, N)
x = np.outer(np.cos(u), np.sin(v))
y = np.outer(np.sin(u), np.sin(v))
z = np.outer(np.ones(np.size(u)), np.cos(v))
ax.plot_surface(x, y, z, linewidth=0.0, cstride=stride, rstride=stride)
ax.set_title('{0}x{0} data points, stride={1}'.format(N,stride))

N=200
stride=2
ax = axes[1,0]
u = np.linspace(0, 2 * np.pi, N)
v = np.linspace(0, np.pi, N)
x = np.outer(np.cos(u), np.sin(v))
y = np.outer(np.sin(u), np.sin(v))
z = np.outer(np.ones(np.size(u)), np.cos(v))
ax.plot_surface(x, y, z, linewidth=0.0, cstride=stride, rstride=stride)
ax.set_title('{0}x{0} data points, stride={1}'.format(N,stride))

N=200
stride=1
ax = axes[1,1]
u = np.linspace(0, 2 * np.pi, N)
v = np.linspace(0, np.pi, N)
x = np.outer(np.cos(u), np.sin(v))
y = np.outer(np.sin(u), np.sin(v))
z = np.outer(np.ones(np.size(u)), np.cos(v))
ax.plot_surface(x, y, z, linewidth=0.0, cstride=stride, rstride=stride)
ax.set_title('{0}x{0} data points, stride={1}'.format(N,stride))

plt.show()

结果图形如下:

result of the above code

如您所见,图的结果对数据的密度和stride关键字都是敏感的。尽管您要提供的数据量要小心-plot_surface()会花费大量时间来提供结果。希望这会有所帮助。