matplotlib表面图超出轴限制

4 投票
2 回答
5120 浏览
提问于 2025-04-18 04:50

我想在Matplotlib中画一个好看的抛物面,像这样:

这里输入图片描述

但我现在得到的效果是这个:

这里输入图片描述

你看,顶部没有“切掉”。我试过把抛物面顶部半径外的Z数组的所有值都去掉,但这样会导致边缘很 jagged(锯齿状)。有人能帮帮我吗?

这是我的代码:

from matplotlib import *
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
from pylab import *
import math
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

X = np.arange(-5, 5, 0.1)
Y = np.arange(-5, 5, 0.1)
X, Y = np.meshgrid(X, Y)
Z = (X**2 + Y**2)

ax.set_zlim(-10, 20)

ax.plot_surface(X, Y, Z,  alpha=0.9, rstride=4, cstride=4, linewidth=0.5, cmap=cm.summer)

plt.show()

2 个回答

2

手动数据裁剪

我见过的一种有效方法是手动裁剪数据; 比如,你的例子可以更新为

from matplotlib import *
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
from pylab import *
import math
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

X = np.arange(-5, 5, 0.1)
Y = np.arange(-5, 5, 0.1)
X, Y = np.meshgrid(X, Y)
Z = (X**2 + Y**2)

ax.set_zlim(-10, 20)

for i in range(len(X)):
    for j in range(len(Y)):
        if (Z[j,i] < -10) or (Z[j,i] > 20):
            Z[j,i] = NaN


ax.plot_surface(X, Y, Z,  alpha=0.9, rstride=4, cstride=4, linewidth=0.5, cmap=cm.summer)

plt.show()

注意

在这种情况下,可以用很简洁的方式来完成这个操作,使用

Z[Z>20] = NaN

最终得到

在这里输入图片描述

4

为了将来参考,我想到用圆柱坐标来描述这个表面,结果看起来正是我想要的样子:

在这里输入图片描述

from matplotlib import *
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
from pylab import *
import math
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

r = T = np.arange(0, 2*pi, 0.01)
r, T = np.meshgrid(r, T)
#Parametrise it
X = r*np.cos(T)
Y = r*np.sin(T)
Z = r**2

ax.plot_surface(X, Y, Z,  alpha=0.9, rstride=10, cstride=10, linewidth=0.5, cmap=cm.summer)

plt.show()

我想这很有道理:处理圆柱形物体时,使用圆柱坐标!

撰写回答