Matplotlib忽略3D p中的负值

2024-04-25 23:47:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我必须绘制一个三维函数,它有无意义的负值(它们不应该出现在绘图中)。必须绘制的函数如下:

def constraint_function(x, y):
    return min(
        (1800 - 0.3 * x - 0.5 * y) / 0.4,
        (500 - 0.1 * x - 0.08 * y) / 0.12,
        (200 - 0.06 * x - 0.04 * y) / 0.05
    )

我用以下方法计算函数:

^{pr2}$

该函数的有效值大多在[0, 3600]x[0, 3600]中。我采用的第一种方法是设置轴限制以满足我的需要:

fig = plt.figure()

ax = fig.add_subplot(111, projection='3d')
ax.azim = 20
ax.set_xlim(0, 3500)
ax.set_ylim(0, 3500)
ax.set_zlim(0, 4500)
ax.plot_surface(xs, ys, zs)

plt.show()

结果如下图:

enter image description here 它只是忽略了限制,无论如何都在策划它。第二种方法是将负值定义为np.nan,将函数改为:

def constraint_function(x, y):
    temp = min(
        (1800 - 0.3 * x - 0.5 * y) / 0.4,
        (500 - 0.1 * x - 0.08 * y) / 0.12,
        (200 - 0.06 * x - 0.04 * y) / 0.05
    )
    return temp if temp >= 0 else np.nan

将无效值的alpha设置为零:

plt.cm.jet.set_bad(alpha=0.0)
ax.azim = 20
ax.set_xlim(0, 3500)
ax.set_ylim(0, 3500)
ax.set_zlim(0, 4500)

ax.plot_surface(xs, ys, zs)

plt.show()

enter image description here 它给我留下了锯一样的边界,这也是我不想拥有的东西。有没有一种方法可以消除这些边缘,并在情节转负时得到一条平滑的线条?在


Tags: 方法函数returndeffig绘制functionplt
2条回答

首先,z值数组轴是相反的;它应该是zs[iy][ix]而不是zs[ix][iy]。正因为如此,你的情节被左右颠倒了。在

其次,通过在Python中迭代构建z数组要慢得多;您应该委托给numpy,如下所示:

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

# create axis sample
xs = np.linspace(0, 3600, 1000)
ys = np.linspace(0, 3600, 1000)

# create mesh samples
xxs, yys = np.meshgrid(xs, ys)

# create data
zzs = np.min([
    ((1800 - 0.30 * xxs - 0.50 * yys) / 0.40),
    (( 500 - 0.10 * xxs - 0.08 * yys) / 0.12),
    (( 200 - 0.06 * xxs - 0.04 * yys) / 0.05)
], axis=0)

# clip data which is below 0.0
zzs[zzs < 0.] = np.NaN

NumPy矢量化操作速度快很多倍。在

第三,你的代码没有什么特别的错误,只是采样分辨率太低;把它设置得更高

^{pr2}$

生产

enter image description here

从技术上讲,你可以使网格倾斜,这样会导致zick-zack模式的网格点发生移动,从而使它们位于一条直线上。在

如下所示。在

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

x=np.linspace(-5,5,6)
X,Y = np.meshgrid(x,x)
Z = X+Y

X[Z==-2] = X[Z==-2]+1
Y[Z==-2] = Y[Z==-2]+1
Z[Z==-2] = 0
Z[Z<0] = np.nan

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

ax.set_zlim(0, 12)
ax.plot_surface(X, Y, Z)

plt.show()

enter image description here

现在的问题是将这种方法推广到任意曲面。当然有可能,但还需要一些工作。在

相关问题 更多 >