如何使用 matplotlib 在 python 中绘制一个完美光滑的球体?
How to plot a perfectly smooth sphere in python using matplotlib?
我正在尝试使用 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()
我得到的图附在下面:
生成的图形由其上的矩形曲面块组成。是否有可能平滑边界或使其难以区分并制作一个完美光滑的球体?
Matplotlib 通过将 3d 表面分解成颜色相同的小子多边形来绘制 3d 表面,如 documentation 中所述,因此您的结果并不令人意外。为了获得更光滑的表面,您必须提供更多的数据点。但是,有一个小问题,那就是 plot_surface()
可能不会使用您提供的所有数据。这是通过 cstride
和 rstride
关键字控制的。我不太清楚默认值是如何计算的,但下面是一个演示效果的小例子:
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()
结果图如下所示:
如您所见,绘图的结果对数据密度和 stride
关键字都很敏感。请注意您提供的数据量——plot_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()
我得到的图附在下面:
生成的图形由其上的矩形曲面块组成。是否有可能平滑边界或使其难以区分并制作一个完美光滑的球体?
Matplotlib 通过将 3d 表面分解成颜色相同的小子多边形来绘制 3d 表面,如 documentation 中所述,因此您的结果并不令人意外。为了获得更光滑的表面,您必须提供更多的数据点。但是,有一个小问题,那就是 plot_surface()
可能不会使用您提供的所有数据。这是通过 cstride
和 rstride
关键字控制的。我不太清楚默认值是如何计算的,但下面是一个演示效果的小例子:
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()
结果图如下所示:
如您所见,绘图的结果对数据密度和 stride
关键字都很敏感。请注意您提供的数据量——plot_surface()
可能会占用大量时间来提供结果。希望这有帮助。